Mass refactor 💥
This commit is contained in:
parent
6dfacdf04c
commit
8f1d0070c3
13
.travis.yml
13
.travis.yml
@ -3,19 +3,8 @@ language: c
|
||||
install:
|
||||
- _libsodium_version=0.7.0
|
||||
- _weechat_version=v1.0
|
||||
- _libjansson_version=v2.5
|
||||
|
||||
# install libjansson
|
||||
- git clone git://github.com/akheron/jansson.git
|
||||
- pushd jansson
|
||||
- git checkout tags/${_libjansson_version}
|
||||
- autoreconf -i
|
||||
- ./configure --prefix=/usr
|
||||
- make -j3
|
||||
- sudo make install
|
||||
- popd
|
||||
|
||||
# install libsodium (needed for libtoxcore)
|
||||
# install libsodium (libtoxcore dependency)
|
||||
- git clone git://github.com/jedisct1/libsodium.git
|
||||
- pushd libsodium
|
||||
- git checkout tags/${_libsodium_version}
|
||||
|
@ -32,24 +32,24 @@ endif()
|
||||
set(INSTALL_PATH "${INSTALL_PATH}" CACHE PATH "Path to install the plugin binary to.")
|
||||
|
||||
add_library(tox MODULE
|
||||
src/tox-weechat.c
|
||||
src/tox-weechat-identities.c
|
||||
src/tox-weechat-chats.c
|
||||
src/tox-weechat-friend-requests.c
|
||||
src/tox-weechat-tox-callbacks.c
|
||||
src/tox-weechat-commands.c
|
||||
src/tox-weechat-gui.c
|
||||
src/tox-weechat-utils.c
|
||||
src/tox-weechat-config.c
|
||||
src/tox-weechat-data.c
|
||||
src/tox-weechat-completion.c
|
||||
src/tox-weechat-messages.c
|
||||
src/twc.c
|
||||
src/twc-bootstrap.c
|
||||
src/twc-chat.c
|
||||
src/twc-commands.c
|
||||
src/twc-completion.c
|
||||
src/twc-config.c
|
||||
src/twc-friend-request.c
|
||||
src/twc-gui.c
|
||||
src/twc-list.c
|
||||
src/twc-message-queue.c
|
||||
src/twc-profile.c
|
||||
src/twc-tox-callbacks.c
|
||||
src/twc-utils.c
|
||||
)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror-implicit-function-declaration -Wno-unused-parameter")
|
||||
|
||||
target_link_libraries(tox toxcore)
|
||||
target_link_libraries(tox jansson)
|
||||
|
||||
# remove lib prefix (libtox.so -> tox.so)
|
||||
set_target_properties(tox PROPERTIES PREFIX "")
|
||||
|
31
README.md
31
README.md
@ -1,6 +1,6 @@
|
||||
Tox-WeeChat
|
||||
===========
|
||||
Tox-WeeChat is a C plugin for the [WeeChat][1] chat client that enables it to connect to the [Tox][2] network. It is functional, but fairly limited in features and not intended for general use yet.
|
||||
Tox-WeeChat is a plugin for [WeeChat][1] that enables it to connect to the [Tox][2] network. It is functional, but currently only intended for experimental use.
|
||||
|
||||
Current build status: [![Build Status](https://travis-ci.org/haavardp/tox-weechat.svg?branch=master)](https://travis-ci.org/haavardp/tox-weechat)
|
||||
|
||||
@ -8,37 +8,35 @@ Installation
|
||||
------------
|
||||
> Tox-WeeChat is available in the [AUR][3].
|
||||
|
||||
Tox-WeeChat requires [WeeChat][1] >=1.0, [libjansson][4] >=2.5, and the latest-ish [libtoxcore][5]. It also requires CMake to be built. Installation is fairly simple; after getting the source, compile and install using CMake:
|
||||
Tox-WeeChat requires [WeeChat][1] >= 1.0 and the latest-ish [libtoxcore][4]. It also requires CMake to be built. Installation is fairly simple; after getting the source, compile and install using CMake:
|
||||
|
||||
$ mkdir build && cd build
|
||||
$ cmake -DHOME_FOLDER_INSTALL=ON ..
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
This installs the plugin binary `tox.so` to the recommended location `~/.weechat/plugins`. Omitting the home folder flag installs to `/usr/local/lib/weechat/plugins`. Installing to a custom WeeChat home or similar is achieved by setting `INSTALL_PATH`.
|
||||
This installs the plugin binary `tox.so` to the recommended location `~/.weechat/plugins`. Without the home folder flag, the binary is placed in `/usr/local/lib/weechat/plugins`. Installing to a custom WeeChat folder or elsewhere is achieved by setting `INSTALL_PATH`.
|
||||
|
||||
Usage
|
||||
-----
|
||||
- If the plugin does no automatically load, load it with `/plugin load tox`. You may have to specify the full path to the plugin binary.
|
||||
- Create a new identity with `/tox create <name>`. The data file is stored in `~/.weechat/tox/` by default.
|
||||
- Connect your identity to the Tox network with `/tox connect <name>`.
|
||||
- Create a new profile with `/tox create <name>`. The data file is stored in `~/.weechat/tox/` by default.
|
||||
- Load your profile and connect to the Tox network with `/tox load <name>`.
|
||||
- Change your name with `/name <new name>`.
|
||||
- Get your Tox ID with `/myid`.
|
||||
- To add friends or respond to friend requests, `/help friend` will get you started.
|
||||
- Message a friend with `/msg <friend number>`. Get their friend number with `/friend list`.
|
||||
|
||||
A list of commands is available with `/help -list tox`.
|
||||
Run `/help -list tox` to get a list of all available commands.
|
||||
|
||||
TODO & Implemented features
|
||||
TODO
|
||||
----
|
||||
- [x] Adding friends, one-to-one chats
|
||||
- [x] Support multiple identities
|
||||
- [x] Save friend requests
|
||||
- [ ] Encrypted save files
|
||||
- [ ] Tox DNS
|
||||
- [ ] Group chats (awaiting libtoxcore implementation)
|
||||
- [ ] Support proxies (TOR)
|
||||
- [ ] A/V (long term)
|
||||
- Persist data (friend requests etc.)
|
||||
- Support encrypted save files
|
||||
- Tox DNS
|
||||
- Group chats
|
||||
- Support proxies (e.g. TOR)
|
||||
- A/V
|
||||
|
||||
License
|
||||
---------
|
||||
@ -62,6 +60,5 @@ along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
[1]: http://weechat.org
|
||||
[2]: http://tox.im
|
||||
[3]: https://aur.archlinux.org/packages/tox-weechat-git
|
||||
[4]: http://www.digip.org/jansson/
|
||||
[5]: https://github.com/irungentoo/toxcore
|
||||
[4]: https://github.com/irungentoo/toxcore
|
||||
|
||||
|
@ -1,225 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-identities.h"
|
||||
#include "tox-weechat-messages.h"
|
||||
#include "tox-weechat-utils.h"
|
||||
|
||||
#include "tox-weechat-chats.h"
|
||||
|
||||
const char *tox_weechat_tag_unsent_message = "tox_unsent";
|
||||
const char *tox_weechat_tag_sent_message = "tox_sent";
|
||||
const char *tox_weechat_tag_received_message = "tox_received";
|
||||
|
||||
int tox_weechat_buffer_input_callback(void *data,
|
||||
struct t_gui_buffer *buffer,
|
||||
const char *input_data);
|
||||
|
||||
int tox_weechat_buffer_close_callback(void *data,
|
||||
struct t_gui_buffer *buffer);
|
||||
|
||||
void
|
||||
tox_weechat_chat_add(struct t_tox_weechat_identity *identity,
|
||||
struct t_tox_weechat_chat *chat)
|
||||
{
|
||||
chat->identity = identity;
|
||||
|
||||
chat->prev_chat = identity->last_chat;
|
||||
chat->next_chat = NULL;
|
||||
|
||||
if (identity->chats == NULL)
|
||||
identity->chats = chat;
|
||||
else
|
||||
identity->last_chat->next_chat = chat;
|
||||
|
||||
identity->last_chat = chat;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_chat_remove(struct t_tox_weechat_chat *chat)
|
||||
{
|
||||
if (chat->prev_chat)
|
||||
chat->prev_chat->next_chat = chat->next_chat;
|
||||
if (chat->next_chat)
|
||||
chat->next_chat->prev_chat = chat->prev_chat;
|
||||
|
||||
if (chat == chat->identity->chats)
|
||||
chat->identity->chats = chat->next_chat;
|
||||
if (chat == chat->identity->last_chat)
|
||||
chat->identity->last_chat = chat->prev_chat;
|
||||
|
||||
free(chat);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_chat_refresh(struct t_tox_weechat_chat *chat)
|
||||
{
|
||||
char *name = tox_weechat_get_name_nt(chat->identity->tox,
|
||||
chat->friend_number);
|
||||
char *status_message = tox_weechat_get_status_message_nt(chat->identity->tox,
|
||||
chat->friend_number);
|
||||
|
||||
weechat_buffer_set(chat->buffer, "short_name", name);
|
||||
weechat_buffer_set(chat->buffer, "title", status_message);
|
||||
|
||||
free(name);
|
||||
free(status_message);
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_chat_refresh_timer_callback(void *data, int remaining)
|
||||
{
|
||||
struct t_tox_weechat_chat *chat = data;
|
||||
tox_weechat_chat_refresh(chat);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_chat_queue_refresh(struct t_tox_weechat_chat *chat)
|
||||
{
|
||||
weechat_hook_timer(1, 0, 1,
|
||||
tox_weechat_chat_refresh_timer_callback, chat);
|
||||
}
|
||||
|
||||
struct t_tox_weechat_chat *
|
||||
tox_weechat_friend_chat_new(struct t_tox_weechat_identity *identity,
|
||||
int32_t friend_number)
|
||||
{
|
||||
struct t_tox_weechat_chat *chat = malloc(sizeof(*chat));
|
||||
chat->friend_number = friend_number;
|
||||
chat->identity = identity;
|
||||
|
||||
uint8_t client_id[TOX_CLIENT_ID_SIZE];
|
||||
tox_get_client_id(identity->tox, friend_number, client_id);
|
||||
|
||||
// TODO: prepend identity name
|
||||
char buffer_name[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
tox_weechat_bin2hex(client_id, TOX_CLIENT_ID_SIZE, buffer_name);
|
||||
|
||||
chat->buffer = weechat_buffer_new(buffer_name,
|
||||
tox_weechat_buffer_input_callback, chat,
|
||||
tox_weechat_buffer_close_callback, chat);
|
||||
tox_weechat_chat_refresh(chat);
|
||||
tox_weechat_chat_add(identity, chat);
|
||||
|
||||
return chat;
|
||||
}
|
||||
|
||||
struct t_tox_weechat_chat *
|
||||
tox_weechat_get_existing_friend_chat(struct t_tox_weechat_identity *identity,
|
||||
int32_t friend_number)
|
||||
{
|
||||
for (struct t_tox_weechat_chat *chat = identity->chats;
|
||||
chat;
|
||||
chat = chat->next_chat)
|
||||
{
|
||||
if (chat->friend_number == friend_number)
|
||||
return chat;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct t_tox_weechat_chat *
|
||||
tox_weechat_get_friend_chat(struct t_tox_weechat_identity *identity,
|
||||
int32_t friend_number)
|
||||
{
|
||||
struct t_tox_weechat_chat *chat = tox_weechat_get_existing_friend_chat(identity, friend_number);
|
||||
|
||||
if (chat)
|
||||
return chat;
|
||||
else
|
||||
return tox_weechat_friend_chat_new(identity, friend_number);
|
||||
}
|
||||
|
||||
struct t_tox_weechat_chat *
|
||||
tox_weechat_get_chat_for_buffer(struct t_gui_buffer *buffer)
|
||||
{
|
||||
for (struct t_tox_weechat_identity *identity = tox_weechat_identities;
|
||||
identity;
|
||||
identity = identity->next_identity)
|
||||
{
|
||||
for (struct t_tox_weechat_chat *chat = identity->chats;
|
||||
chat;
|
||||
chat = chat->next_chat)
|
||||
{
|
||||
if (chat->buffer == buffer)
|
||||
return chat;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_chat_print_message(struct t_tox_weechat_chat *chat,
|
||||
const char *sender,
|
||||
const char *message,
|
||||
const char *tags)
|
||||
{
|
||||
weechat_printf_tags(chat->buffer, tags, "%s\t%s", sender, message);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_chat_print_action(struct t_tox_weechat_chat *chat,
|
||||
const char *sender,
|
||||
const char *message,
|
||||
const char *tags)
|
||||
{
|
||||
weechat_printf_tags(chat->buffer, tags,
|
||||
"%s%s %s",
|
||||
weechat_prefix("action"),
|
||||
sender, message);
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_buffer_input_callback(void *data,
|
||||
struct t_gui_buffer *weechat_buffer,
|
||||
const char *input_data)
|
||||
{
|
||||
struct t_tox_weechat_chat *chat = data;
|
||||
int rc = tox_weechat_send_friend_message(chat->identity,
|
||||
chat->friend_number,
|
||||
input_data);
|
||||
|
||||
char *name = tox_weechat_get_self_name_nt(chat->identity->tox);
|
||||
tox_weechat_chat_print_message(chat, "", name, input_data);
|
||||
free(name);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_buffer_close_callback(void *data,
|
||||
struct t_gui_buffer *weechat_buffer)
|
||||
{
|
||||
struct t_tox_weechat_chat *chat = data;
|
||||
tox_weechat_chat_remove(chat);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_CHATS_H
|
||||
#define TOX_WEECHAT_CHATS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
extern const char *tox_weechat_tag_unsent_message;
|
||||
extern const char *tox_weechat_tag_sent_message;
|
||||
extern const char *tox_weechat_tag_received_message;
|
||||
|
||||
struct t_tox_weechat_chat
|
||||
{
|
||||
struct t_gui_buffer *buffer;
|
||||
|
||||
int32_t friend_number;
|
||||
|
||||
struct t_tox_weechat_identity *identity;
|
||||
|
||||
struct t_tox_weechat_chat *next_chat;
|
||||
struct t_tox_weechat_chat *prev_chat;
|
||||
};
|
||||
|
||||
struct t_tox_weechat_chat *
|
||||
tox_weechat_get_friend_chat(struct t_tox_weechat_identity *identity,
|
||||
int32_t friend_number);
|
||||
|
||||
struct t_tox_weechat_chat *
|
||||
tox_weechat_get_existing_friend_chat(struct t_tox_weechat_identity *identity,
|
||||
int32_t friend_number);
|
||||
|
||||
struct t_tox_weechat_chat *
|
||||
tox_weechat_get_chat_for_buffer(struct t_gui_buffer *target_buffer);
|
||||
|
||||
void tox_weechat_chat_print_message(struct t_tox_weechat_chat *chat,
|
||||
const char *sender,
|
||||
const char *message,
|
||||
const char *tags);
|
||||
|
||||
void tox_weechat_chat_print_action(struct t_tox_weechat_chat *chat,
|
||||
const char *sender,
|
||||
const char *message,
|
||||
const char *tags);
|
||||
|
||||
void
|
||||
tox_weechat_chat_refresh(struct t_tox_weechat_chat *chat);
|
||||
|
||||
void
|
||||
tox_weechat_chat_queue_refresh(struct t_tox_weechat_chat *chat);
|
||||
|
||||
#endif // TOX_WEECHAT_CHATS_H
|
@ -1,762 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-utils.h"
|
||||
#include "tox-weechat-identities.h"
|
||||
#include "tox-weechat-chats.h"
|
||||
#include "tox-weechat-friend-requests.h"
|
||||
|
||||
#include "tox-weechat-commands.h"
|
||||
|
||||
// TODO: something
|
||||
extern int
|
||||
tox_weechat_bootstrap_tox(Tox *tox, char *address, uint16_t port, char *public_key);
|
||||
|
||||
int
|
||||
tox_weechat_cmd_bootstrap(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
if (!identity)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (argc != 4)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
char *address = argv[1];
|
||||
uint16_t port = atoi(argv[2]);
|
||||
char *tox_address = argv[3];
|
||||
|
||||
if (!tox_weechat_bootstrap_tox(identity->tox, address, port, tox_address))
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sInvalid arguments for bootstrap.",
|
||||
weechat_prefix("error"));
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_cmd_friend(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
if (!identity)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (argc == 1 || (argc == 2 && weechat_strcasecmp(argv[1], "list") == 0))
|
||||
{
|
||||
size_t friend_count = tox_count_friendlist(identity->tox);
|
||||
int32_t friend_numbers[friend_count];
|
||||
tox_get_friendlist(identity->tox, friend_numbers, friend_count);
|
||||
|
||||
if (friend_count == 0)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sYou have no friends :(",
|
||||
weechat_prefix("network"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%s[#] Name [client ID]",
|
||||
weechat_prefix("network"));
|
||||
|
||||
for (size_t i = 0; i < friend_count; ++i)
|
||||
{
|
||||
int32_t friend_number = friend_numbers[i];
|
||||
char *name = tox_weechat_get_name_nt(identity->tox, friend_number);
|
||||
|
||||
uint8_t client_id[TOX_CLIENT_ID_SIZE];
|
||||
tox_get_client_id(identity->tox, friend_number, client_id);
|
||||
char hex_address[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
tox_weechat_bin2hex(client_id,
|
||||
TOX_CLIENT_ID_SIZE,
|
||||
hex_address);
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%s[%d] %s [%s]",
|
||||
weechat_prefix("network"),
|
||||
friend_number, name, hex_address);
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
else if (argc >= 3 && (weechat_strcasecmp(argv[1], "add") == 0))
|
||||
{
|
||||
char address[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_weechat_hex2bin(argv[2], TOX_FRIEND_ADDRESS_SIZE * 2, address);
|
||||
|
||||
char *message;
|
||||
if (argc == 3 || strlen(argv_eol[3]) == 0)
|
||||
message = "Hi! Please add me on Tox!";
|
||||
else
|
||||
message = argv_eol[3];
|
||||
|
||||
int32_t result = tox_add_friend(identity->tox,
|
||||
(uint8_t *)address,
|
||||
(uint8_t *)message,
|
||||
strlen(message));
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case TOX_FAERR_TOOLONG:
|
||||
weechat_printf(identity->buffer,
|
||||
"%sFriend request message too long! Try again.",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_ALREADYSENT:
|
||||
weechat_printf(identity->buffer,
|
||||
"%sYou have already sent a friend request to that address.",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_OWNKEY:
|
||||
weechat_printf(identity->buffer,
|
||||
"%sYou can't add yourself as a friend.",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_BADCHECKSUM:
|
||||
weechat_printf(identity->buffer,
|
||||
"%sInvalid friend address - try again.",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_NOMEM:
|
||||
weechat_printf(identity->buffer,
|
||||
"%sCould not add friend (out of memory).",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_UNKNOWN:
|
||||
case TOX_FAERR_SETNEWNOSPAM:
|
||||
case TOX_FAERR_NOMESSAGE:
|
||||
weechat_printf(identity->buffer,
|
||||
"%sCould not add friend (unknown error).",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
default:
|
||||
weechat_printf(identity->buffer,
|
||||
"%sFriend request sent!",
|
||||
weechat_prefix("network"));
|
||||
break;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
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(identity->tox, friend_number))
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sInvalid friend number.",
|
||||
weechat_prefix("error"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
char *name = tox_weechat_get_name_nt(identity->tox, friend_number);
|
||||
if (tox_del_friend(identity->tox, friend_number) == 0)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sRemoved %s from friend list.",
|
||||
weechat_prefix("network"), name);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sCould not remove friend!",
|
||||
weechat_prefix("error"));
|
||||
}
|
||||
|
||||
free(name);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
else if (argc == 3 &&
|
||||
(weechat_strcasecmp(argv[1], "accept") == 0
|
||||
|| weechat_strcasecmp(argv[1], "decline") == 0))
|
||||
{
|
||||
int accept = weechat_strcasecmp(argv[1], "accept") == 0;
|
||||
|
||||
struct t_tox_weechat_friend_request *request;
|
||||
if (weechat_strcasecmp(argv[2], "all") == 0)
|
||||
{
|
||||
int count = 0;
|
||||
while ((request = tox_weechat_friend_request_with_num(identity, 0)) != NULL)
|
||||
{
|
||||
if (accept)
|
||||
tox_weechat_accept_friend_request(request);
|
||||
else
|
||||
tox_weechat_decline_friend_request(request);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%s%s %d friend requests.",
|
||||
weechat_prefix("network"),
|
||||
accept ? "Accepted" : "Declined",
|
||||
count);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *endptr;
|
||||
unsigned long num = strtoul(argv[2], &endptr, 10);
|
||||
if (endptr == argv[2] || (request = tox_weechat_friend_request_with_num(identity, num)) == NULL)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sInvalid friend request ID.",
|
||||
weechat_prefix("error"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
char hex_address[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
tox_weechat_bin2hex(request->tox_id,
|
||||
TOX_CLIENT_ID_SIZE,
|
||||
hex_address);
|
||||
|
||||
if (accept)
|
||||
tox_weechat_accept_friend_request(request);
|
||||
else
|
||||
tox_weechat_decline_friend_request(request);
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%s%s friend request from %s.",
|
||||
weechat_prefix("network"),
|
||||
accept ? "Accepted" : "Declined",
|
||||
hex_address);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
}
|
||||
|
||||
else if (argc == 2 && weechat_strcasecmp(argv[1], "requests") == 0)
|
||||
{
|
||||
if (identity->friend_requests == NULL)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sNo pending friend requests :(",
|
||||
weechat_prefix("network"));
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sPending friend requests:",
|
||||
weechat_prefix("network"));
|
||||
|
||||
int num = 0;
|
||||
for (struct t_tox_weechat_friend_request *request = identity->friend_requests;
|
||||
request;
|
||||
request = request->next_request)
|
||||
{
|
||||
char hex_address[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
tox_weechat_bin2hex(request->tox_id,
|
||||
TOX_CLIENT_ID_SIZE,
|
||||
hex_address);
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%s[%d] Address: %s\n"
|
||||
"[%d] Message: %s",
|
||||
weechat_prefix("network"),
|
||||
num, hex_address,
|
||||
num, request->message);
|
||||
|
||||
++num;
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_cmd_me(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc == 1)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
struct t_tox_weechat_chat *chat = tox_weechat_get_chat_for_buffer(buffer);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
tox_send_action(identity->tox,
|
||||
chat->friend_number,
|
||||
(uint8_t *)argv_eol[1],
|
||||
strlen(argv_eol[1]));
|
||||
|
||||
char *name = tox_weechat_get_self_name_nt(identity->tox);
|
||||
tox_weechat_chat_print_action(chat, "", name, argv_eol[1]);
|
||||
|
||||
free(name);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_cmd_msg(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc == 1)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
if (!identity)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: command \"%s\" must be executed in a Tox buffer",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
argv[0]);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
char *endptr;
|
||||
unsigned long friend_number = strtoul(argv[1], &endptr, 10);
|
||||
|
||||
if (endptr == argv[1] || !tox_friend_exists(identity->tox, friend_number))
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sInvalid friend number.",
|
||||
weechat_prefix("error"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
struct t_tox_weechat_chat *chat = tox_weechat_get_friend_chat(identity, friend_number);
|
||||
if (argc >= 3)
|
||||
{
|
||||
tox_send_message(identity->tox,
|
||||
friend_number,
|
||||
(uint8_t *)argv_eol[2],
|
||||
strlen(argv_eol[2]));
|
||||
char *name = tox_weechat_get_self_name_nt(identity->tox);
|
||||
tox_weechat_chat_print_message(chat, "", name, argv_eol[2]);
|
||||
free(name);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_cmd_myid(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
if (!identity)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: command \"%s\" must be executed in a Tox buffer",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
argv[0]);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(identity->tox, address);
|
||||
|
||||
char address_str[TOX_FRIEND_ADDRESS_SIZE * 2 + 1];
|
||||
tox_weechat_bin2hex(address, TOX_FRIEND_ADDRESS_SIZE, address_str);
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%sYour Tox address: %s",
|
||||
weechat_prefix("network"),
|
||||
address_str);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_cmd_name(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc == 1)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
if (!identity)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
char *name = argv_eol[1];
|
||||
|
||||
int result = tox_set_name(identity->tox, (uint8_t *)name, strlen(name));
|
||||
if (result == -1)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%s%s",
|
||||
weechat_prefix("error"),
|
||||
"Could not change name.");
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
weechat_bar_item_update("input_prompt");
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%sYou are now known as %s",
|
||||
weechat_prefix("network"),
|
||||
name);
|
||||
|
||||
for (struct t_tox_weechat_chat *chat = identity->chats;
|
||||
chat;
|
||||
chat = chat->next_chat)
|
||||
{
|
||||
weechat_printf(chat->buffer,
|
||||
"%sYou are now known as %s",
|
||||
weechat_prefix("network"),
|
||||
name);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_cmd_status(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc != 2)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
if (!identity)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: command \"%s\" must be executed in a Tox buffer",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
argv[0]);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
TOX_USERSTATUS status = TOX_USERSTATUS_INVALID;
|
||||
if (weechat_strcasecmp(argv[1], "online") == 0)
|
||||
status = TOX_USERSTATUS_NONE;
|
||||
else if (weechat_strcasecmp(argv[1], "busy") == 0)
|
||||
status = TOX_USERSTATUS_BUSY;
|
||||
else if (weechat_strcasecmp(argv[1], "away") == 0)
|
||||
status = TOX_USERSTATUS_AWAY;
|
||||
|
||||
if (status == TOX_USERSTATUS_INVALID)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
tox_set_user_status(identity->tox, status);
|
||||
weechat_bar_item_update("away");
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_cmd_statusmsg(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
if (!identity)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: command \"%s\" must be executed in a Tox buffer",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
argv[0]);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
char *message = argc > 1 ? argv_eol[1] : " ";
|
||||
|
||||
int result = tox_set_status_message(identity->tox,
|
||||
(uint8_t *)message,
|
||||
strlen(message));
|
||||
if (result == -1)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%s%s",
|
||||
weechat_prefix("error"),
|
||||
"Could not set status message.");
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_cmd_tox(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc == 1 || (argc == 2 && weechat_strcasecmp(argv[1], "list") == 0))
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%sAll Tox identities:",
|
||||
weechat_prefix("network"));
|
||||
for (struct t_tox_weechat_identity *identity = tox_weechat_identities;
|
||||
identity;
|
||||
identity = identity->next_identity)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s",
|
||||
weechat_prefix("network"),
|
||||
identity->name);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
else if (argc == 3 && (weechat_strcasecmp(argv[1], "create") == 0))
|
||||
{
|
||||
char *name = argv[2];
|
||||
|
||||
if (tox_weechat_identity_name_search(name))
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: Identity \"%s\" already exists!",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
name);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_new(name);
|
||||
weechat_printf(NULL,
|
||||
"%s%s: Identity \"%s\" created!",
|
||||
weechat_prefix("network"),
|
||||
weechat_plugin->name,
|
||||
identity->name);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
else if (argc >= 3 && argc <= 4
|
||||
&& (weechat_strcasecmp(argv[1], "delete") == 0))
|
||||
{
|
||||
char *name = argv[2];
|
||||
char *flag = argv[3];
|
||||
|
||||
struct t_tox_weechat_identity *identity;
|
||||
if ((identity = tox_weechat_identity_name_search(name)))
|
||||
{
|
||||
if (argc == 4 && strcmp(flag, "-keepdata") == 0)
|
||||
{
|
||||
tox_weechat_identity_delete(identity, false);
|
||||
}
|
||||
else if (argc == 4 && strcmp(flag, "-yes") == 0)
|
||||
{
|
||||
tox_weechat_identity_delete(identity, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: You must confirm deletion with either "
|
||||
"\"-keepdata\" or \"-yes\" (see /help tox)",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
weechat_printf(NULL,
|
||||
"%s%s: Identity \"%s\" has been deleted.",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
name);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: Identity \"%s\" does not exist.",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
identity->name);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
else if (argc >= 3 && (weechat_strcasecmp(argv[1], "connect") == 0))
|
||||
{
|
||||
for (int i = 2; i < argc; ++i)
|
||||
{
|
||||
char *name = argv[i];
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_name_search(name);
|
||||
if (!identity)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: Identity \"%s\" does not exist.",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
name);
|
||||
}
|
||||
else
|
||||
{
|
||||
tox_weechat_identity_connect(identity);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
else if (argc >= 3 && (weechat_strcasecmp(argv[1], "disconnect") == 0))
|
||||
{
|
||||
for (int i = 2; i < argc; ++i)
|
||||
{
|
||||
char *name = argv[i];
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_name_search(name);
|
||||
if (!identity)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: Identity \"%s\" does not exist.",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
name);
|
||||
}
|
||||
else
|
||||
{
|
||||
tox_weechat_identity_disconnect(identity);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_commands_init()
|
||||
{
|
||||
weechat_hook_command("bootstrap",
|
||||
"bootstrap the Tox DHT",
|
||||
"<address> <port> <client id>",
|
||||
" address: internet address of node to bootstrap with\n"
|
||||
" port: port of the node\n"
|
||||
"client id: Tox client of the node",
|
||||
NULL, tox_weechat_cmd_bootstrap, NULL);
|
||||
|
||||
weechat_hook_command("friend",
|
||||
"manage friends",
|
||||
"list"
|
||||
" || add <address> [<message>]"
|
||||
" || remove <number>"
|
||||
" || requests"
|
||||
" || accept <number>|all"
|
||||
" || decline <number>|all",
|
||||
" list: list all friends\n"
|
||||
" add: add a friend by their public Tox address\n"
|
||||
"requests: list friend requests\n"
|
||||
" accept: accept friend requests\n"
|
||||
" decline: decline friend requests\n",
|
||||
NULL, tox_weechat_cmd_friend, NULL);
|
||||
|
||||
weechat_hook_command("me",
|
||||
"send an action to the current chat",
|
||||
"<message>",
|
||||
"message: message to send",
|
||||
NULL, tox_weechat_cmd_me, NULL);
|
||||
|
||||
weechat_hook_command("msg",
|
||||
"send a message to a Tox friend",
|
||||
"<id> [<message>]",
|
||||
" id: friend number of the person to message\n"
|
||||
"message: message to send",
|
||||
NULL, tox_weechat_cmd_msg, NULL);
|
||||
|
||||
weechat_hook_command("myid",
|
||||
"get your Tox ID to give to friends",
|
||||
"", "",
|
||||
NULL, tox_weechat_cmd_myid, NULL);
|
||||
|
||||
weechat_hook_command("name",
|
||||
"change your Tox name",
|
||||
"<name>",
|
||||
"name: your new name",
|
||||
NULL, tox_weechat_cmd_name, NULL);
|
||||
|
||||
weechat_hook_command("status",
|
||||
"change your Tox status",
|
||||
"online|busy|away",
|
||||
"",
|
||||
NULL, tox_weechat_cmd_status, NULL);
|
||||
|
||||
weechat_hook_command("statusmsg",
|
||||
"change your Tox status message",
|
||||
"[<message>]",
|
||||
"message: your new status message",
|
||||
NULL, tox_weechat_cmd_statusmsg, NULL);
|
||||
|
||||
weechat_hook_command("tox",
|
||||
"manage Tox identities",
|
||||
"list"
|
||||
" || create <name>"
|
||||
" || delete <name> -yes|-keepdata"
|
||||
" || connect [<name>...]"
|
||||
" || disconnect [<name>...]",
|
||||
" list: list all Tox identity\n"
|
||||
" create: create a new Tox identity\n"
|
||||
" delete: delete a Tox identity; requires either "
|
||||
"-yes to confirm deletion or -keepdata to delete the "
|
||||
"identity but keep the Tox data file\n"
|
||||
" connect: connect a Tox identity to the network\n"
|
||||
"disconnect: connect a Tox identity to the network\n",
|
||||
"list"
|
||||
" || create"
|
||||
" || delete %(tox_identities) -yes|-keepdata"
|
||||
" || connect %(tox_disconnected_identities)|%*"
|
||||
" || disconnect %(tox_connected_identities)|%*",
|
||||
tox_weechat_cmd_tox, NULL);
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-identities.h"
|
||||
|
||||
#include "tox-weechat-completion.h"
|
||||
|
||||
enum
|
||||
{
|
||||
TOX_WEECHAT_ALL_IDENTITIES,
|
||||
TOX_WEECHAT_CONNECTED_IDENTITIES,
|
||||
TOX_WEECHAT_DISCONNECTED_IDENTITIES,
|
||||
};
|
||||
|
||||
int
|
||||
tox_weechat_completion_identity(void *data,
|
||||
const char *completion_item,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_gui_completion *completion)
|
||||
{
|
||||
int flag = (int)(intptr_t)data;
|
||||
|
||||
for (struct t_tox_weechat_identity *identity = tox_weechat_identities;
|
||||
identity;
|
||||
identity = identity->next_identity)
|
||||
{
|
||||
if (flag == TOX_WEECHAT_ALL_IDENTITIES
|
||||
|| (flag == TOX_WEECHAT_CONNECTED_IDENTITIES && identity->tox != NULL)
|
||||
|| (flag == TOX_WEECHAT_DISCONNECTED_IDENTITIES && identity->tox == NULL))
|
||||
{
|
||||
weechat_hook_completion_list_add(completion,
|
||||
identity->name,
|
||||
0,
|
||||
WEECHAT_LIST_POS_SORT);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_completion_init()
|
||||
{
|
||||
weechat_hook_completion("tox_identities",
|
||||
"identity",
|
||||
tox_weechat_completion_identity,
|
||||
(void *)(intptr_t)TOX_WEECHAT_ALL_IDENTITIES);
|
||||
weechat_hook_completion("tox_connected_identities",
|
||||
"identity",
|
||||
tox_weechat_completion_identity,
|
||||
(void *)(intptr_t)TOX_WEECHAT_CONNECTED_IDENTITIES);
|
||||
weechat_hook_completion("tox_disconnected_identities",
|
||||
"identity",
|
||||
tox_weechat_completion_identity,
|
||||
(void *)(intptr_t)TOX_WEECHAT_DISCONNECTED_IDENTITIES);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
#ifndef TOX_WEECHAT_COMPLETION_H
|
||||
#define TOX_WEECHAT_COMPLETION_H
|
||||
|
||||
void
|
||||
tox_weechat_completion_init();
|
||||
|
||||
#endif // TOX_WEECHAT_COMPLETION_H
|
@ -1,257 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-identities.h"
|
||||
|
||||
#include "tox-weechat-config.h"
|
||||
|
||||
struct t_config_file *tox_weechat_config_file = NULL;
|
||||
struct t_config_section *tox_weechat_config_section_identity = NULL;
|
||||
|
||||
char *tox_weechat_identity_option_names[TOX_WEECHAT_IDENTITY_NUM_OPTIONS] =
|
||||
{
|
||||
"save_file",
|
||||
"autoconnect",
|
||||
"max_friend_requests",
|
||||
};
|
||||
|
||||
char *tox_weechat_identity_option_defaults[TOX_WEECHAT_IDENTITY_NUM_OPTIONS] =
|
||||
{
|
||||
"%h/tox/%n",
|
||||
"off",
|
||||
"100",
|
||||
};
|
||||
|
||||
int
|
||||
tox_weechat_config_identity_option_search(const char *option_name)
|
||||
{
|
||||
for (int i = 0; i < TOX_WEECHAT_IDENTITY_NUM_OPTIONS; ++i)
|
||||
{
|
||||
if (strcmp(tox_weechat_identity_option_names[i], option_name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_config_identity_read_callback(void *data,
|
||||
struct t_config_file *config_file,
|
||||
struct t_config_section *section,
|
||||
const char *option_name,
|
||||
const char *value)
|
||||
{
|
||||
int rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
|
||||
|
||||
if (option_name)
|
||||
{
|
||||
char *dot_pos = strrchr(option_name, '.');
|
||||
if (dot_pos)
|
||||
{
|
||||
char *identity_name = weechat_strndup(option_name,
|
||||
dot_pos-option_name);
|
||||
char *option_name = dot_pos + 1;
|
||||
if (identity_name)
|
||||
{
|
||||
int option_index = tox_weechat_config_identity_option_search(option_name);
|
||||
if (option_index >= 0)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity =
|
||||
tox_weechat_identity_name_search(identity_name);
|
||||
|
||||
if (!identity)
|
||||
identity = tox_weechat_identity_new(identity_name);
|
||||
|
||||
if (identity)
|
||||
{
|
||||
rc = weechat_config_option_set(identity->options[option_index],
|
||||
value, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: error creating identity \"%s\"",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
identity_name);
|
||||
}
|
||||
}
|
||||
|
||||
free(identity_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == WEECHAT_CONFIG_OPTION_SET_ERROR)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: error creating identity option \"%s\"",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
option_name);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_config_identity_write_callback(void *data,
|
||||
struct t_config_file *config_file,
|
||||
const char *section_name)
|
||||
{
|
||||
if (!weechat_config_write_line (config_file, section_name, NULL))
|
||||
return WEECHAT_CONFIG_WRITE_ERROR;
|
||||
|
||||
for (struct t_tox_weechat_identity *identity = tox_weechat_identities;
|
||||
identity;
|
||||
identity = identity->next_identity)
|
||||
{
|
||||
for (int i = 0; i < TOX_WEECHAT_IDENTITY_NUM_OPTIONS; ++i)
|
||||
{
|
||||
if (!weechat_config_write_option(tox_weechat_config_file,
|
||||
identity->options[i]))
|
||||
{
|
||||
return WEECHAT_CONFIG_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_CONFIG_WRITE_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_config_identity_check_value_callback(void *data,
|
||||
struct t_config_option *option,
|
||||
const char *value)
|
||||
{
|
||||
return 1; // ok, 0 not ok
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_config_identity_change_callback(void *data,
|
||||
struct t_config_option *option)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_config_init()
|
||||
{
|
||||
|
||||
tox_weechat_config_file = weechat_config_new("tox", NULL, NULL);
|
||||
|
||||
tox_weechat_config_section_identity =
|
||||
weechat_config_new_section(tox_weechat_config_file, "identity",
|
||||
0, 0,
|
||||
tox_weechat_config_identity_read_callback, NULL,
|
||||
tox_weechat_config_identity_write_callback, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
struct t_config_option *
|
||||
tox_weechat_config_init_option(int option_index, const char *option_name)
|
||||
{
|
||||
switch (option_index)
|
||||
{
|
||||
case TOX_WEECHAT_IDENTITY_OPTION_AUTOCONNECT:
|
||||
return weechat_config_new_option(
|
||||
tox_weechat_config_file, tox_weechat_config_section_identity,
|
||||
option_name, "boolean",
|
||||
"automatically connect to the Tox network when WeeChat starts",
|
||||
NULL, 0, 0,
|
||||
tox_weechat_identity_option_defaults[option_index],
|
||||
NULL,
|
||||
0,
|
||||
tox_weechat_config_identity_check_value_callback, NULL,
|
||||
tox_weechat_config_identity_change_callback, NULL,
|
||||
NULL, NULL);
|
||||
case TOX_WEECHAT_IDENTITY_OPTION_MAX_FRIEND_REQUESTS:
|
||||
return weechat_config_new_option(
|
||||
tox_weechat_config_file, tox_weechat_config_section_identity,
|
||||
option_name, "integer",
|
||||
"maximum amount of friend requests to retain before dropping "
|
||||
"new ones",
|
||||
NULL, 0, INT_MAX,
|
||||
tox_weechat_identity_option_defaults[option_index],
|
||||
NULL,
|
||||
0,
|
||||
tox_weechat_config_identity_check_value_callback, NULL,
|
||||
tox_weechat_config_identity_change_callback, NULL,
|
||||
NULL, NULL);
|
||||
case TOX_WEECHAT_IDENTITY_OPTION_SAVEFILE:
|
||||
return weechat_config_new_option(
|
||||
tox_weechat_config_file, tox_weechat_config_section_identity,
|
||||
option_name, "string",
|
||||
"path to Tox data file (\"%h\" will be replaced by WeeChat "
|
||||
"home, \"%n\" by the identity name); will be created if it does "
|
||||
"not exist.",
|
||||
NULL, 0, 0,
|
||||
tox_weechat_identity_option_defaults[option_index],
|
||||
NULL,
|
||||
0,
|
||||
tox_weechat_config_identity_check_value_callback, NULL,
|
||||
tox_weechat_config_identity_change_callback, NULL,
|
||||
NULL, NULL);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_config_init_identity(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
for (int i = 0; i < TOX_WEECHAT_IDENTITY_NUM_OPTIONS; ++i)
|
||||
{
|
||||
// length: name + . + option + \0
|
||||
size_t length = strlen(identity->name) + 1
|
||||
+ strlen(tox_weechat_identity_option_names[i]) + 1;
|
||||
|
||||
char *option_name = malloc(sizeof(*option_name) * length);
|
||||
if (option_name)
|
||||
{
|
||||
snprintf(option_name, length, "%s.%s",
|
||||
identity->name,
|
||||
tox_weechat_identity_option_names[i]);
|
||||
|
||||
identity->options[i] = tox_weechat_config_init_option(i, option_name);
|
||||
free (option_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_config_read()
|
||||
{
|
||||
return weechat_config_read(tox_weechat_config_file);
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_config_write()
|
||||
{
|
||||
return weechat_config_write(tox_weechat_config_file);
|
||||
}
|
@ -1,301 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/////// TODO //////////
|
||||
// get rid of data from deleted/nonexisting identities so it doesn't accumulate
|
||||
///////////////////////
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-identities.h"
|
||||
#include "tox-weechat-friend-requests.h"
|
||||
#include "tox-weechat-messages.h"
|
||||
#include "tox-weechat-utils.h"
|
||||
|
||||
#include "tox-weechat-data.h"
|
||||
|
||||
#define TOX_WEECHAT_JSON_CONFIG_PATH "%h/tox/data.json"
|
||||
|
||||
const char *tox_weechat_json_key_friend_requests = "friend_requests";
|
||||
const char *tox_weechat_json_friend_request_key_client_id = "client_id";
|
||||
const char *tox_weechat_json_friend_request_key_message = "message";
|
||||
const char *tox_weechat_json_key_unsent_messages = "unsent_messages";
|
||||
const char *tox_weechat_json_unsent_messages_key_recipient_id = "recipient_id";
|
||||
|
||||
json_t *tox_weechat_json_data = NULL;
|
||||
|
||||
/**
|
||||
* Return the full path to the JSON data file.
|
||||
*/
|
||||
char *
|
||||
tox_weechat_json_data_file_path()
|
||||
{
|
||||
const char *weechat_dir = weechat_info_get("weechat_dir", NULL);
|
||||
return weechat_string_replace(TOX_WEECHAT_JSON_CONFIG_PATH, "%h", weechat_dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key used for an identity in the JSON data file. Must be freed.
|
||||
*/
|
||||
char *
|
||||
tox_weechat_json_get_identity_key(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(identity->tox, address);
|
||||
|
||||
char *hex_id = malloc(TOX_CLIENT_ID_SIZE * 2 + 1);
|
||||
tox_weechat_bin2hex(address, TOX_CLIENT_ID_SIZE, hex_id);
|
||||
|
||||
return hex_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an identity's friend requests into a json array.
|
||||
*/
|
||||
json_t *
|
||||
tox_weechat_data_friend_requests_json(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
json_t *friend_request_array = json_array();
|
||||
if (!friend_request_array)
|
||||
return NULL;
|
||||
|
||||
for (struct t_tox_weechat_friend_request *request = identity->friend_requests;
|
||||
request;
|
||||
request = request->next_request)
|
||||
{
|
||||
char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
tox_weechat_bin2hex(request->tox_id, TOX_CLIENT_ID_SIZE, hex_id);
|
||||
|
||||
json_t *json_request = json_object();
|
||||
json_t *json_id = json_string(hex_id);
|
||||
json_t *json_message = json_string(request->message);
|
||||
if (!json_request || !json_id || !json_message)
|
||||
break;
|
||||
|
||||
json_object_set_new(json_request,
|
||||
tox_weechat_json_friend_request_key_client_id,
|
||||
json_id);
|
||||
|
||||
json_object_set_new(json_request,
|
||||
tox_weechat_json_friend_request_key_message,
|
||||
json_message);
|
||||
|
||||
json_array_append_new(friend_request_array, json_request);
|
||||
}
|
||||
|
||||
return friend_request_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an identity's unsent messages into a json object.
|
||||
*/
|
||||
json_t *
|
||||
tox_weechat_data_unsent_messages_json(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
json_t *messages_object = json_object();
|
||||
if (!messages_object)
|
||||
return NULL;
|
||||
|
||||
for (struct t_tox_weechat_unsent_message_recipient *recipient = identity->unsent_message_recipients;
|
||||
recipient;
|
||||
recipient = recipient->next_recipient)
|
||||
{
|
||||
if (!(recipient->unsent_messages))
|
||||
continue;
|
||||
|
||||
char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
tox_weechat_bin2hex(recipient->recipient_id, TOX_CLIENT_ID_SIZE, hex_id);
|
||||
|
||||
json_t *json_messages = json_array();
|
||||
if (!json_messages)
|
||||
break;
|
||||
|
||||
for (struct t_tox_weechat_unsent_message *message = recipient->unsent_messages;
|
||||
message;
|
||||
message = message->next_message)
|
||||
{
|
||||
json_t *json_message = json_string(message->message);
|
||||
if (!json_message)
|
||||
break;
|
||||
|
||||
json_array_append_new(json_messages, json_message);
|
||||
}
|
||||
|
||||
json_object_set_new(messages_object, hex_id, json_messages);
|
||||
}
|
||||
|
||||
return messages_object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an identity's data.
|
||||
*/
|
||||
void
|
||||
tox_weechat_data_identity_save(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
json_t *json_data = json_object();
|
||||
if (!json_data)
|
||||
return;
|
||||
|
||||
json_t *friend_requests = tox_weechat_data_friend_requests_json(identity);
|
||||
json_object_set_new(json_data,
|
||||
tox_weechat_json_key_friend_requests,
|
||||
friend_requests);
|
||||
|
||||
json_t *unsent_messages = tox_weechat_data_unsent_messages_json(identity);
|
||||
json_object_set_new(json_data,
|
||||
tox_weechat_json_key_unsent_messages,
|
||||
unsent_messages);
|
||||
|
||||
char *identity_key = tox_weechat_json_get_identity_key(identity);
|
||||
json_object_set_new(tox_weechat_json_data, identity_key, json_data);
|
||||
free(identity_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load friend requests from a json array.
|
||||
*/
|
||||
void
|
||||
tox_weechat_data_load_friend_requests(struct t_tox_weechat_identity *identity,
|
||||
json_t *friend_requests)
|
||||
{
|
||||
tox_weechat_friend_request_free_identity(identity);
|
||||
|
||||
size_t index;
|
||||
json_t *json_request;
|
||||
json_array_foreach(friend_requests, index, json_request)
|
||||
{
|
||||
char client_id[TOX_CLIENT_ID_SIZE];
|
||||
const char *message;
|
||||
|
||||
json_t *json_id = json_object_get(json_request,
|
||||
tox_weechat_json_friend_request_key_client_id);
|
||||
json_t *json_message = json_object_get(json_request,
|
||||
tox_weechat_json_friend_request_key_message);
|
||||
|
||||
tox_weechat_hex2bin(json_string_value(json_id), TOX_CLIENT_ID_SIZE * 2, client_id);
|
||||
message = json_string_value(json_message);
|
||||
|
||||
tox_weechat_friend_request_add(identity,
|
||||
(uint8_t *)client_id,
|
||||
message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load unsent messages from a json array.
|
||||
*/
|
||||
void
|
||||
tox_weechat_data_load_unsent_messages(struct t_tox_weechat_identity *identity,
|
||||
json_t *recipient_object)
|
||||
{
|
||||
tox_weechat_unsent_messages_free(identity);
|
||||
|
||||
const char *key;
|
||||
json_t *message_array;
|
||||
json_object_foreach(recipient_object, key, message_array)
|
||||
{
|
||||
uint8_t client_id[TOX_CLIENT_ID_SIZE];
|
||||
tox_weechat_hex2bin(key, TOX_CLIENT_ID_SIZE * 2, (char *)client_id);
|
||||
|
||||
size_t index;
|
||||
json_t *message;
|
||||
json_array_foreach(message_array, index, message)
|
||||
{
|
||||
tox_weechat_add_unsent_message(identity,
|
||||
client_id,
|
||||
json_string_value(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an identity's data from a JSON object.
|
||||
*/
|
||||
void
|
||||
tox_weechat_data_identity_load(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
char *identity_key = tox_weechat_json_get_identity_key(identity);
|
||||
json_t *identity_data = json_object_get(tox_weechat_json_data, identity_key);
|
||||
free(identity_key);
|
||||
|
||||
json_t *friend_requests = json_object_get(identity_data,
|
||||
tox_weechat_json_key_friend_requests);
|
||||
if (friend_requests)
|
||||
tox_weechat_data_load_friend_requests(identity, friend_requests);
|
||||
|
||||
json_t *unsent_messages = json_object_get(identity_data,
|
||||
tox_weechat_json_key_unsent_messages);
|
||||
if (unsent_messages)
|
||||
tox_weechat_data_load_unsent_messages(identity, unsent_messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the data on disk into memory.
|
||||
*/
|
||||
void
|
||||
tox_weechat_data_load()
|
||||
{
|
||||
char *full_path = tox_weechat_json_data_file_path();
|
||||
|
||||
|
||||
json_error_t error;
|
||||
tox_weechat_json_data = json_load_file(full_path, 0, &error);
|
||||
free(full_path);
|
||||
|
||||
if (!tox_weechat_json_data)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: could not load on-disk data",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name);
|
||||
|
||||
tox_weechat_json_data = json_object();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all in-memory data to data on disk. Return 0 on success, -1 on
|
||||
* error.
|
||||
*/
|
||||
int
|
||||
tox_weechat_data_save()
|
||||
{
|
||||
char *full_path = tox_weechat_json_data_file_path();
|
||||
int rc = json_dump_file(tox_weechat_json_data,
|
||||
full_path,
|
||||
0);
|
||||
free(full_path);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free in-memory JSON data.
|
||||
*/
|
||||
void
|
||||
tox_weechat_data_free()
|
||||
{
|
||||
json_decref(tox_weechat_json_data);
|
||||
}
|
||||
|
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-identities.h"
|
||||
#include "tox-weechat-utils.h"
|
||||
|
||||
#include "tox-weechat-friend-requests.h"
|
||||
|
||||
/**
|
||||
* Add a new friend request to an identity.
|
||||
*
|
||||
* Returns 0 on success, -1 on a full friend list.
|
||||
*/
|
||||
int
|
||||
tox_weechat_friend_request_add(struct t_tox_weechat_identity *identity,
|
||||
const uint8_t *client_id,
|
||||
const char *message)
|
||||
{
|
||||
// check friend request count
|
||||
struct t_config_option *option =
|
||||
identity->options[TOX_WEECHAT_IDENTITY_OPTION_MAX_FRIEND_REQUESTS];
|
||||
unsigned int max_requests = weechat_config_integer(option);
|
||||
|
||||
if (identity->friend_request_count >= max_requests)
|
||||
return -1;
|
||||
|
||||
struct t_tox_weechat_friend_request *request = malloc(sizeof(*request));
|
||||
request->identity = identity;
|
||||
request->message = strdup(message);
|
||||
memcpy(request->tox_id, client_id, TOX_CLIENT_ID_SIZE);
|
||||
|
||||
// add to list
|
||||
request->prev_request = identity->last_friend_request;
|
||||
request->next_request = NULL;
|
||||
|
||||
if (identity->friend_requests == NULL)
|
||||
identity->friend_requests = request;
|
||||
else
|
||||
identity->last_friend_request->next_request = request;
|
||||
|
||||
identity->last_friend_request = request;
|
||||
++(identity->friend_request_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and free a friend request from its identity.
|
||||
*/
|
||||
void
|
||||
tox_weechat_friend_request_remove(struct t_tox_weechat_friend_request *request)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = request->identity;
|
||||
if (request == identity->last_friend_request)
|
||||
identity->last_friend_request = request->prev_request;
|
||||
|
||||
if (request->prev_request)
|
||||
request->prev_request->next_request = request->next_request;
|
||||
else
|
||||
identity->friend_requests = request->next_request;
|
||||
|
||||
if (request->next_request)
|
||||
request->next_request->prev_request = request->prev_request;
|
||||
|
||||
--(identity->friend_request_count);
|
||||
|
||||
tox_weechat_friend_request_free(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept a friend request. Remove and free the request.
|
||||
*/
|
||||
void
|
||||
tox_weechat_accept_friend_request(struct t_tox_weechat_friend_request *request)
|
||||
{
|
||||
tox_add_friend_norequest(request->identity->tox, request->tox_id);
|
||||
tox_weechat_friend_request_remove(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decline a friend request. Remove and free the request.
|
||||
*/
|
||||
void
|
||||
tox_weechat_decline_friend_request(struct t_tox_weechat_friend_request *request)
|
||||
{
|
||||
tox_weechat_friend_request_remove(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the friend request from the identity with the number num.
|
||||
*/
|
||||
struct t_tox_weechat_friend_request *
|
||||
tox_weechat_friend_request_with_num(struct t_tox_weechat_identity *identity,
|
||||
unsigned int num)
|
||||
{
|
||||
if (num >= identity->friend_request_count) return NULL;
|
||||
|
||||
unsigned int i = 0;
|
||||
struct t_tox_weechat_friend_request *request = identity->friend_requests;
|
||||
while (i != num && request->next_request)
|
||||
{
|
||||
request = request->next_request;
|
||||
++i;
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a friend request.
|
||||
*/
|
||||
void
|
||||
tox_weechat_friend_request_free(struct t_tox_weechat_friend_request *request)
|
||||
{
|
||||
free(request->message);
|
||||
free(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all friend requests from an identity.
|
||||
*/
|
||||
void
|
||||
tox_weechat_friend_request_free_identity(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
while (identity->friend_requests)
|
||||
tox_weechat_friend_request_remove(identity->friend_requests);
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_FRIEND_REQUESTS_H
|
||||
#define TOX_WEECHAT_FRIEND_REQUESTS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
/**
|
||||
* Represents a friend request with a Tox ID and a message.
|
||||
*/
|
||||
struct t_tox_weechat_friend_request
|
||||
{
|
||||
uint8_t tox_id[TOX_CLIENT_ID_SIZE];
|
||||
char *message;
|
||||
|
||||
struct t_tox_weechat_identity *identity;
|
||||
|
||||
struct t_tox_weechat_friend_request *next_request;
|
||||
struct t_tox_weechat_friend_request *prev_request;
|
||||
};
|
||||
|
||||
int
|
||||
tox_weechat_friend_request_add(struct t_tox_weechat_identity *identity,
|
||||
const uint8_t *client_id,
|
||||
const char *message);
|
||||
|
||||
void
|
||||
tox_weechat_accept_friend_request(struct t_tox_weechat_friend_request *request);
|
||||
|
||||
void
|
||||
tox_weechat_decline_friend_request(struct t_tox_weechat_friend_request *request);
|
||||
|
||||
struct t_tox_weechat_friend_request *
|
||||
tox_weechat_friend_request_with_num(struct t_tox_weechat_identity *identity,
|
||||
unsigned int num);
|
||||
|
||||
void
|
||||
tox_weechat_friend_request_free(struct t_tox_weechat_friend_request *request);
|
||||
|
||||
void
|
||||
tox_weechat_friend_request_free_identity(struct t_tox_weechat_identity *identity);
|
||||
|
||||
#endif // TOX_WEECHAT_FRIEND_REQUESTS_H
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-identities.h"
|
||||
#include "tox-weechat-utils.h"
|
||||
|
||||
#include "tox-weechat-gui.h"
|
||||
|
||||
char *
|
||||
bar_item_away(void *data,
|
||||
struct t_gui_bar_item *item,
|
||||
struct t_gui_window *window,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_hashtable *extra_info)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
|
||||
if (!identity || !(identity->tox))
|
||||
return NULL;
|
||||
|
||||
char *status = NULL;;
|
||||
switch (tox_get_self_user_status(identity->tox))
|
||||
{
|
||||
case TOX_USERSTATUS_BUSY:
|
||||
status = strdup("busy");
|
||||
break;
|
||||
case TOX_USERSTATUS_AWAY:
|
||||
status = strdup("away");
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
char *
|
||||
bar_item_input_prompt(void *data,
|
||||
struct t_gui_bar_item *item,
|
||||
struct t_gui_window *window,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_hashtable *extra_info)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
|
||||
if (!identity || !(identity->tox))
|
||||
return NULL;
|
||||
|
||||
return tox_weechat_get_self_name_nt(identity->tox);
|
||||
}
|
||||
|
||||
char *
|
||||
bar_item_buffer_plugin(void *data, struct t_gui_bar_item *item,
|
||||
struct t_gui_window *window,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_hashtable *extra_info)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = tox_weechat_identity_for_buffer(buffer);
|
||||
|
||||
char string[256];
|
||||
|
||||
const char *plugin_name = weechat_plugin_get_name(weechat_plugin);
|
||||
const char *identity_name = identity->name;
|
||||
|
||||
snprintf(string, sizeof(string),
|
||||
"%s%s/%s%s%s/%s%s",
|
||||
plugin_name,
|
||||
weechat_color("bar_delim"),
|
||||
weechat_color("bar_fg"),
|
||||
identity_name,
|
||||
weechat_color("bar_delim"),
|
||||
weechat_color("bar_fg"),
|
||||
identity->tox_online ? "online" : "offline");
|
||||
|
||||
return strdup(string);
|
||||
}
|
||||
|
||||
void tox_weechat_gui_init()
|
||||
{
|
||||
weechat_bar_item_new("away", bar_item_away, NULL);
|
||||
weechat_bar_item_new("input_prompt", bar_item_input_prompt, NULL);
|
||||
weechat_bar_item_new("buffer_plugin", bar_item_buffer_plugin, NULL);
|
||||
}
|
||||
|
@ -1,459 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-config.h"
|
||||
#include "tox-weechat-friend-requests.h"
|
||||
#include "tox-weechat-chats.h"
|
||||
#include "tox-weechat-tox-callbacks.h"
|
||||
#include "tox-weechat-utils.h"
|
||||
#include "tox-weechat-data.h"
|
||||
|
||||
#include "tox-weechat-identities.h"
|
||||
|
||||
struct t_tox_weechat_identity *tox_weechat_identities = NULL;
|
||||
struct t_tox_weechat_identity *tox_weechat_last_identity = NULL;
|
||||
|
||||
char *tox_weechat_bootstrap_addresses[] = {
|
||||
"192.254.75.98",
|
||||
"31.7.57.236",
|
||||
"107.161.17.51",
|
||||
"144.76.60.215",
|
||||
"23.226.230.47",
|
||||
"37.59.102.176",
|
||||
"37.187.46.132",
|
||||
"178.21.112.187",
|
||||
"192.210.149.121",
|
||||
"54.199.139.199",
|
||||
"63.165.243.15",
|
||||
};
|
||||
uint16_t tox_weechat_bootstrap_ports[] = {
|
||||
33445, 443, 33445, 33445, 33445,
|
||||
33445, 33445, 33445, 33445, 33445,
|
||||
443,
|
||||
};
|
||||
|
||||
char *tox_weechat_bootstrap_keys[] = {
|
||||
"951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F",
|
||||
"2A4B50D1D525DA2E669592A20C327B5FAD6C7E5962DC69296F9FEC77C4436E4E",
|
||||
"7BE3951B97CA4B9ECDDA768E8C52BA19E9E2690AB584787BF4C90E04DBB75111",
|
||||
"04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F",
|
||||
"A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074",
|
||||
"B98A2CEAA6C6A2FADC2C3632D284318B60FE5375CCB41EFA081AB67F500C1B0B",
|
||||
"5EB67C51D3FF5A9D528D242B669036ED2A30F8A60E674C45E7D43010CB2E1331",
|
||||
"4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057",
|
||||
"F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67",
|
||||
"7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029",
|
||||
"8CD087E31C67568103E8C2A28653337E90E6B8EDA0D765D57C6B5172B4F1F04C",
|
||||
};
|
||||
|
||||
int tox_weechat_bootstrap_count = sizeof(tox_weechat_bootstrap_addresses)
|
||||
/ sizeof(tox_weechat_bootstrap_addresses[0]);
|
||||
|
||||
char *
|
||||
tox_weechat_identity_data_file_path(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
// expand path
|
||||
const char *weechat_dir = weechat_info_get ("weechat_dir", NULL);
|
||||
const char *base_path = weechat_config_string(identity->options[TOX_WEECHAT_IDENTITY_OPTION_SAVEFILE]);
|
||||
char *home_expanded = weechat_string_replace(base_path, "%h", weechat_dir);
|
||||
char *full_path = weechat_string_replace(home_expanded, "%n", identity->name);
|
||||
free(home_expanded);
|
||||
|
||||
return full_path;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_load_identity_data_file(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
char *full_path = tox_weechat_identity_data_file_path(identity);
|
||||
|
||||
FILE *file = fopen(full_path, "r");
|
||||
free(full_path);
|
||||
|
||||
if (file)
|
||||
{
|
||||
// get file size
|
||||
fseek(file, 0, SEEK_END);
|
||||
size_t size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
// allocate a buffer and read file into it
|
||||
uint8_t *data = malloc(sizeof(*data) * size);
|
||||
fread(data, sizeof(uint8_t), size, file);
|
||||
fclose(file);
|
||||
|
||||
// try loading the data
|
||||
int status = tox_load(identity->tox, data, size);
|
||||
free(data);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_save_identity_data_file(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
char *full_path = tox_weechat_identity_data_file_path(identity);
|
||||
|
||||
char *rightmost_slash = strrchr(full_path, '/');
|
||||
char *save_dir = weechat_strndup(full_path, rightmost_slash - full_path);
|
||||
weechat_mkdir_parents(save_dir, 0755);
|
||||
free(save_dir);
|
||||
|
||||
// save Tox data to a buffer
|
||||
uint32_t size = tox_size(identity->tox);
|
||||
uint8_t *data = malloc(sizeof(*data) * size);
|
||||
tox_save(identity->tox, data);
|
||||
|
||||
// save buffer to a file
|
||||
FILE *file = fopen(full_path, "w");
|
||||
if (file)
|
||||
{
|
||||
fwrite(data, sizeof(data[0]), size, file);
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
tox_weechat_identity_buffer_close_callback(void *data,
|
||||
struct t_gui_buffer *buffer)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
identity->buffer = NULL;
|
||||
|
||||
tox_weechat_identity_disconnect(identity);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
tox_weechat_bootstrap_tox(Tox *tox, const char *address, uint16_t port, const char *public_key)
|
||||
{
|
||||
char binary_key[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_weechat_hex2bin(public_key, TOX_FRIEND_ADDRESS_SIZE * 2, binary_key);
|
||||
|
||||
int result = tox_bootstrap_from_address(tox,
|
||||
address,
|
||||
port,
|
||||
(uint8_t *)binary_key);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_bootstrap_random_node(Tox *tox)
|
||||
{
|
||||
int i = rand() % tox_weechat_bootstrap_count;
|
||||
tox_weechat_bootstrap_tox(tox, tox_weechat_bootstrap_addresses[i],
|
||||
tox_weechat_bootstrap_ports[i],
|
||||
tox_weechat_bootstrap_keys[i]);
|
||||
}
|
||||
|
||||
struct t_tox_weechat_identity *
|
||||
tox_weechat_identity_new(const char *name)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = malloc(sizeof(*identity));
|
||||
identity->name = strdup(name);
|
||||
|
||||
// add to identity list
|
||||
identity->prev_identity= tox_weechat_last_identity;
|
||||
identity->next_identity = NULL;
|
||||
|
||||
if (tox_weechat_identities == NULL)
|
||||
tox_weechat_identities = identity;
|
||||
else
|
||||
tox_weechat_last_identity->next_identity = identity;
|
||||
|
||||
tox_weechat_last_identity = identity;
|
||||
|
||||
// set up internal vars
|
||||
identity->tox = NULL;
|
||||
identity->buffer = NULL;
|
||||
identity->tox_do_timer = NULL;
|
||||
identity->chats = identity->last_chat = NULL;
|
||||
identity->friend_requests = identity->last_friend_request = NULL;
|
||||
identity->unsent_message_recipients = identity->last_unsent_message_recipient = NULL;
|
||||
identity->tox_online = false;
|
||||
|
||||
// set up config
|
||||
tox_weechat_config_init_identity(identity);
|
||||
|
||||
return identity;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_identity_connect(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
if (identity->tox)
|
||||
return;
|
||||
|
||||
// create main buffer
|
||||
if (identity->buffer == NULL)
|
||||
{
|
||||
identity->buffer = weechat_buffer_new(identity->name,
|
||||
NULL, NULL,
|
||||
tox_weechat_identity_buffer_close_callback, identity);
|
||||
}
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%s%s: identity %s connecting...",
|
||||
weechat_prefix("network"),
|
||||
weechat_plugin->name,
|
||||
identity->name);
|
||||
|
||||
if (identity->friend_request_count > 0)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sYou have %d pending friend requests.",
|
||||
weechat_prefix("network"),
|
||||
identity->friend_request_count);
|
||||
}
|
||||
|
||||
// create Tox
|
||||
identity->tox = tox_new(NULL);
|
||||
|
||||
// try loading Tox saved data
|
||||
if (tox_weechat_load_identity_data_file(identity) == -1)
|
||||
{
|
||||
// we failed to load - set an initial name
|
||||
char *name;
|
||||
|
||||
struct passwd *user_pwd;
|
||||
if ((user_pwd = getpwuid(geteuid())))
|
||||
name = user_pwd->pw_name;
|
||||
else
|
||||
name = "Tox-WeeChat User";
|
||||
|
||||
tox_set_name(identity->tox,
|
||||
(uint8_t *)name, strlen(name));
|
||||
}
|
||||
|
||||
// load data
|
||||
tox_weechat_data_identity_load(identity);
|
||||
|
||||
// bootstrap DHT
|
||||
int max_bootstrap_nodes = 5;
|
||||
int bootstrap_nodes = max_bootstrap_nodes > tox_weechat_bootstrap_count ?
|
||||
tox_weechat_bootstrap_count : max_bootstrap_nodes;
|
||||
for (int i = 0; i < bootstrap_nodes; ++i)
|
||||
tox_weechat_bootstrap_random_node(identity->tox);
|
||||
|
||||
// start Tox_do loop
|
||||
tox_weechat_do_timer_cb(identity, 0);
|
||||
|
||||
// register Tox callbacks
|
||||
tox_callback_friend_message(identity->tox, tox_weechat_friend_message_callback, identity);
|
||||
tox_callback_friend_action(identity->tox, tox_weechat_friend_action_callback, identity);
|
||||
tox_callback_connection_status(identity->tox, tox_weechat_connection_status_callback, identity);
|
||||
tox_callback_name_change(identity->tox, tox_weechat_name_change_callback, identity);
|
||||
tox_callback_user_status(identity->tox, tox_weechat_user_status_callback, identity);
|
||||
tox_callback_status_message(identity->tox, tox_weechat_status_message_callback, identity);
|
||||
tox_callback_friend_request(identity->tox, tox_weechat_callback_friend_request, identity);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_identity_disconnect(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
// check that we're not already disconnected
|
||||
if (!identity->tox)
|
||||
return;
|
||||
|
||||
// save data
|
||||
tox_weechat_data_identity_save(identity);
|
||||
|
||||
// save and kill tox
|
||||
int result = tox_weechat_save_identity_data_file(identity);
|
||||
tox_kill(identity->tox);
|
||||
identity->tox = NULL;
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
char *path = tox_weechat_identity_data_file_path(identity);
|
||||
weechat_printf(NULL,
|
||||
"%s%s: Could not save Tox identity %s to file: %s",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
identity->name,
|
||||
path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
// stop Tox timer
|
||||
weechat_unhook(identity->tox_do_timer);
|
||||
|
||||
// have to refresh and hide bar items even if we were already offline
|
||||
tox_weechat_identity_refresh_online_status(identity);
|
||||
tox_weechat_identity_set_online_status(identity, false);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_identity_autoconnect()
|
||||
{
|
||||
for (struct t_tox_weechat_identity *identity = tox_weechat_identities;
|
||||
identity;
|
||||
identity = identity->next_identity)
|
||||
{
|
||||
if (weechat_config_boolean(identity->options[TOX_WEECHAT_IDENTITY_OPTION_AUTOCONNECT]))
|
||||
tox_weechat_identity_connect(identity);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_identity_refresh_online_status(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
weechat_bar_item_update("buffer_plugin");
|
||||
weechat_bar_item_update("input_prompt");
|
||||
weechat_bar_item_update("away");
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_identity_set_online_status(struct t_tox_weechat_identity *identity,
|
||||
bool online)
|
||||
{
|
||||
if (identity->tox_online ^ online)
|
||||
{
|
||||
identity->tox_online = online;
|
||||
tox_weechat_identity_refresh_online_status(identity);
|
||||
|
||||
struct t_gui_buffer *buffer = identity->buffer ?: NULL;
|
||||
if (identity->tox_online)
|
||||
{
|
||||
weechat_printf(buffer,
|
||||
"%s%s: identity %s connected",
|
||||
weechat_prefix("network"),
|
||||
weechat_plugin->name,
|
||||
identity->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(buffer,
|
||||
"%s%s: identity %s disconnected",
|
||||
weechat_prefix("network"),
|
||||
weechat_plugin->name,
|
||||
identity->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct t_tox_weechat_identity *
|
||||
tox_weechat_identity_name_search(const char *name)
|
||||
{
|
||||
for (struct t_tox_weechat_identity *identity = tox_weechat_identities;
|
||||
identity;
|
||||
identity = identity->next_identity)
|
||||
{
|
||||
if (weechat_strcasecmp(identity->name, name) == 0)
|
||||
return identity;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct t_tox_weechat_identity *
|
||||
tox_weechat_identity_for_buffer(struct t_gui_buffer *buffer)
|
||||
{
|
||||
for (struct t_tox_weechat_identity *identity = tox_weechat_identities;
|
||||
identity;
|
||||
identity = identity->next_identity)
|
||||
{
|
||||
if (identity->buffer == buffer)
|
||||
return identity;
|
||||
|
||||
for (struct t_tox_weechat_chat *chat = identity->chats;
|
||||
chat;
|
||||
chat = chat->next_chat)
|
||||
{
|
||||
if (chat->buffer == buffer)
|
||||
return identity;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_identity_delete(struct t_tox_weechat_identity *identity,
|
||||
bool delete_data)
|
||||
{
|
||||
char *data_path = tox_weechat_identity_data_file_path(identity);
|
||||
|
||||
tox_weechat_identity_free(identity);
|
||||
|
||||
if (delete_data)
|
||||
unlink(data_path);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_identity_free(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
// save friend requests
|
||||
tox_weechat_friend_request_free_identity(identity);
|
||||
|
||||
// disconnect
|
||||
tox_weechat_identity_disconnect(identity);
|
||||
|
||||
// close buffer
|
||||
if (identity->buffer)
|
||||
{
|
||||
weechat_buffer_set_pointer(identity->buffer, "close_callback", NULL);
|
||||
weechat_buffer_close(identity->buffer);
|
||||
}
|
||||
|
||||
// remove from list
|
||||
if (identity == tox_weechat_last_identity)
|
||||
tox_weechat_last_identity = identity->prev_identity;
|
||||
|
||||
if (identity->prev_identity)
|
||||
identity->prev_identity->next_identity = identity->next_identity;
|
||||
else
|
||||
tox_weechat_identities = identity->next_identity;
|
||||
|
||||
if (identity->next_identity)
|
||||
identity->next_identity->prev_identity = identity->prev_identity;
|
||||
|
||||
// free remaining vars
|
||||
free(identity->name);
|
||||
free(identity);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_identity_free_all()
|
||||
{
|
||||
while (tox_weechat_identities)
|
||||
tox_weechat_identity_free(tox_weechat_identities);
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_IDENTITIES_H
|
||||
#define TOX_WEECHAT_IDENTITIES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
enum t_tox_weechat_identity_option
|
||||
{
|
||||
TOX_WEECHAT_IDENTITY_OPTION_SAVEFILE = 0,
|
||||
TOX_WEECHAT_IDENTITY_OPTION_AUTOCONNECT,
|
||||
TOX_WEECHAT_IDENTITY_OPTION_MAX_FRIEND_REQUESTS,
|
||||
|
||||
TOX_WEECHAT_IDENTITY_NUM_OPTIONS,
|
||||
};
|
||||
|
||||
struct t_tox_weechat_identity
|
||||
{
|
||||
char *name;
|
||||
struct t_config_option *options[TOX_WEECHAT_IDENTITY_NUM_OPTIONS];
|
||||
|
||||
struct Tox *tox;
|
||||
int tox_online;
|
||||
|
||||
struct t_gui_buffer *buffer;
|
||||
struct t_hook *tox_do_timer;
|
||||
|
||||
struct t_tox_weechat_chat *chats;
|
||||
struct t_tox_weechat_chat *last_chat;
|
||||
|
||||
struct t_tox_weechat_friend_request *friend_requests;
|
||||
struct t_tox_weechat_friend_request *last_friend_request;
|
||||
unsigned int friend_request_count;
|
||||
|
||||
struct t_tox_weechat_unsent_message_recipient *unsent_message_recipients;
|
||||
struct t_tox_weechat_unsent_message_recipient *last_unsent_message_recipient;
|
||||
|
||||
struct t_tox_weechat_identity *next_identity;
|
||||
struct t_tox_weechat_identity *prev_identity;
|
||||
};
|
||||
|
||||
extern struct t_tox_weechat_identity *tox_weechat_identities;
|
||||
extern struct t_tox_weechat_identity *tox_weechat_last_identity;
|
||||
|
||||
struct t_tox_weechat_identity *
|
||||
tox_weechat_identity_new(const char *name);
|
||||
|
||||
void
|
||||
tox_weechat_identity_connect(struct t_tox_weechat_identity *identity);
|
||||
|
||||
void
|
||||
tox_weechat_identity_disconnect(struct t_tox_weechat_identity *identity);
|
||||
|
||||
void
|
||||
tox_weechat_identity_autoconnect();
|
||||
|
||||
void
|
||||
tox_weechat_identity_refresh_online_status(struct t_tox_weechat_identity *identity);
|
||||
|
||||
void
|
||||
tox_weechat_identity_set_online_status(struct t_tox_weechat_identity *identity,
|
||||
bool online);
|
||||
|
||||
struct t_tox_weechat_identity *
|
||||
tox_weechat_identity_name_search(const char *name);
|
||||
|
||||
struct t_tox_weechat_identity *
|
||||
tox_weechat_identity_for_buffer(struct t_gui_buffer *buffer);
|
||||
|
||||
void
|
||||
tox_weechat_identity_delete(struct t_tox_weechat_identity *identity,
|
||||
bool delete_data);
|
||||
|
||||
void
|
||||
tox_weechat_identity_free(struct t_tox_weechat_identity *identity);
|
||||
|
||||
void
|
||||
tox_weechat_identity_free_all();
|
||||
|
||||
#endif // TOX_WEECHAT_IDENTITIES_H
|
@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "tox-weechat-identities.h"
|
||||
#include "tox-weechat-utils.h"
|
||||
|
||||
#include "tox-weechat-messages.h"
|
||||
|
||||
/**
|
||||
* Return an existing unsent message recipient object or NULL.
|
||||
*/
|
||||
struct t_tox_weechat_unsent_message_recipient *
|
||||
tox_weechat_unsent_message_recipient_with_id(struct t_tox_weechat_identity *identity,
|
||||
const uint8_t *id)
|
||||
{
|
||||
struct t_tox_weechat_unsent_message_recipient *recipient;
|
||||
for (recipient = identity->unsent_message_recipients;
|
||||
recipient;
|
||||
recipient = recipient->next_recipient)
|
||||
{
|
||||
if (memcmp(recipient->recipient_id, id, TOX_CLIENT_ID_SIZE) == 0)
|
||||
return recipient;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new unsent message recipient object.
|
||||
*/
|
||||
struct t_tox_weechat_unsent_message_recipient *
|
||||
tox_weechat_unsent_message_recipient_new(struct t_tox_weechat_identity *identity,
|
||||
const uint8_t *id)
|
||||
{
|
||||
struct t_tox_weechat_unsent_message_recipient *recipient = malloc(sizeof(*recipient));
|
||||
if (!recipient)
|
||||
return NULL;
|
||||
|
||||
memcpy(recipient->recipient_id, id, TOX_CLIENT_ID_SIZE);
|
||||
recipient->identity = identity;
|
||||
recipient->unsent_messages = recipient->last_unsent_message = NULL;
|
||||
|
||||
recipient->prev_recipient = identity->last_unsent_message_recipient;
|
||||
recipient->next_recipient = NULL;
|
||||
|
||||
if (identity->unsent_message_recipients == NULL)
|
||||
identity->unsent_message_recipients = recipient;
|
||||
else
|
||||
identity->last_unsent_message_recipient->next_recipient = recipient;
|
||||
|
||||
identity->last_unsent_message_recipient = recipient;
|
||||
|
||||
return recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new message to the unsent messages queue.
|
||||
*/
|
||||
void
|
||||
tox_weechat_add_unsent_message(struct t_tox_weechat_identity *identity,
|
||||
const uint8_t *recipient_id,
|
||||
const char *message)
|
||||
{
|
||||
struct t_tox_weechat_unsent_message_recipient *recipient
|
||||
= tox_weechat_unsent_message_recipient_with_id(identity, recipient_id);
|
||||
if (!recipient)
|
||||
recipient = tox_weechat_unsent_message_recipient_new(identity, recipient_id);
|
||||
if (!recipient)
|
||||
return;
|
||||
|
||||
struct t_tox_weechat_unsent_message *unsent_message = malloc(sizeof(*unsent_message));
|
||||
if (!message)
|
||||
return;
|
||||
|
||||
unsent_message->message = strdup(message);
|
||||
unsent_message->recipient = recipient;
|
||||
|
||||
unsent_message->prev_message = recipient->last_unsent_message;
|
||||
unsent_message->next_message = NULL;
|
||||
|
||||
if (recipient->unsent_messages == NULL)
|
||||
recipient->unsent_messages = unsent_message;
|
||||
else
|
||||
recipient->last_unsent_message->next_message = unsent_message;
|
||||
|
||||
recipient->last_unsent_message = unsent_message;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_remove_unsent_message(struct t_tox_weechat_unsent_message *message)
|
||||
{
|
||||
struct t_tox_weechat_unsent_message_recipient *recipient = message->recipient;
|
||||
if (message == recipient->last_unsent_message)
|
||||
recipient->last_unsent_message = message->prev_message;
|
||||
|
||||
if (message->prev_message)
|
||||
message->prev_message->next_message = message->next_message;
|
||||
else
|
||||
recipient->unsent_messages = message->next_message;
|
||||
|
||||
if (message->next_message)
|
||||
message->next_message->prev_message = message->prev_message;
|
||||
|
||||
free(message->message);
|
||||
free(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to a friend. Does message splitting and queuing.
|
||||
*/
|
||||
uint32_t
|
||||
tox_weechat_send_friend_message(struct t_tox_weechat_identity *identity,
|
||||
int32_t friend_number,
|
||||
const char *message)
|
||||
{
|
||||
// TODO: split message
|
||||
uint32_t rc = tox_send_message(identity->tox,
|
||||
friend_number,
|
||||
(uint8_t *)message,
|
||||
strlen(message));
|
||||
|
||||
uint8_t recipient_id[TOX_CLIENT_ID_SIZE];
|
||||
tox_get_client_id(identity->tox, friend_number, recipient_id);
|
||||
|
||||
if (rc == 0)
|
||||
tox_weechat_add_unsent_message(identity, recipient_id, message);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_unsent_messages_free(struct t_tox_weechat_identity *identity)
|
||||
{
|
||||
struct t_tox_weechat_unsent_message_recipient *recipient;
|
||||
for (recipient = identity->unsent_message_recipients;
|
||||
recipient;
|
||||
recipient = recipient->next_recipient)
|
||||
{
|
||||
while (recipient->unsent_messages)
|
||||
tox_weechat_remove_unsent_message(recipient->unsent_messages);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_attempt_message_flush(struct t_tox_weechat_identity *identity,
|
||||
int32_t friend_number)
|
||||
{
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_MESSAGES_H
|
||||
#define TOX_WEECHAT_MESSAGES_H
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
struct t_tox_weechat_identity;
|
||||
|
||||
struct t_tox_weechat_unsent_message_recipient
|
||||
{
|
||||
uint8_t recipient_id[TOX_CLIENT_ID_SIZE];
|
||||
struct t_tox_weechat_identity *identity;
|
||||
|
||||
struct t_tox_weechat_unsent_message *unsent_messages;
|
||||
struct t_tox_weechat_unsent_message *last_unsent_message;
|
||||
|
||||
struct t_tox_weechat_unsent_message_recipient *next_recipient;
|
||||
struct t_tox_weechat_unsent_message_recipient *prev_recipient;
|
||||
};
|
||||
|
||||
struct t_tox_weechat_unsent_message
|
||||
{
|
||||
char *message;
|
||||
struct t_tox_weechat_unsent_message_recipient *recipient;
|
||||
|
||||
struct t_tox_weechat_unsent_message *next_message;
|
||||
struct t_tox_weechat_unsent_message *prev_message;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
tox_weechat_send_friend_message(struct t_tox_weechat_identity *identity,
|
||||
int32_t friend_number,
|
||||
const char *message);
|
||||
|
||||
void
|
||||
tox_weechat_add_unsent_message(struct t_tox_weechat_identity *identity,
|
||||
const uint8_t *recipient_id,
|
||||
const char *message);
|
||||
|
||||
void
|
||||
tox_weechat_unsent_messages_free(struct t_tox_weechat_identity *identity);
|
||||
|
||||
#endif // TOX_WEECHAT_MESSAGES_H
|
@ -1,214 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "tox-weechat-identities.h"
|
||||
#include "tox-weechat-chats.h"
|
||||
#include "tox-weechat-friend-requests.h"
|
||||
#include "tox-weechat-utils.h"
|
||||
|
||||
#include "tox-weechat-tox-callbacks.h"
|
||||
|
||||
int
|
||||
tox_weechat_do_timer_cb(void *data,
|
||||
int remaining_calls)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
|
||||
if (identity->tox)
|
||||
{
|
||||
tox_do(identity->tox);
|
||||
struct t_hook *hook = weechat_hook_timer(tox_do_interval(identity->tox), 0, 1,
|
||||
tox_weechat_do_timer_cb, identity);
|
||||
identity->tox_do_timer = hook;
|
||||
|
||||
// check connection status
|
||||
int connected = tox_isconnected(identity->tox);
|
||||
tox_weechat_identity_set_online_status(identity, connected);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_friend_message_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
struct t_tox_weechat_chat *chat = tox_weechat_get_friend_chat(identity,
|
||||
friend_number);
|
||||
|
||||
char *name = tox_weechat_get_name_nt(identity->tox, friend_number);
|
||||
char *message_nt = tox_weechat_null_terminate(message, length);
|
||||
|
||||
tox_weechat_chat_print_message(chat, "", name, message_nt);
|
||||
|
||||
free(name);
|
||||
free(message_nt);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_friend_action_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
struct t_tox_weechat_chat *chat = tox_weechat_get_friend_chat(identity,
|
||||
friend_number);
|
||||
|
||||
char *name = tox_weechat_get_name_nt(identity->tox, friend_number);
|
||||
char *message_nt = tox_weechat_null_terminate(message, length);
|
||||
|
||||
tox_weechat_chat_print_action(chat, "", name, message_nt);
|
||||
|
||||
free(name);
|
||||
free(message_nt);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_connection_status_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
uint8_t status,
|
||||
void *data)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
char *name = tox_weechat_get_name_nt(identity->tox, friend_number);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%s%s just went offline.",
|
||||
weechat_prefix("network"),
|
||||
name);
|
||||
}
|
||||
else if (status == 1)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%s%s just came online.",
|
||||
weechat_prefix("network"),
|
||||
name);
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_name_change_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *name,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
struct t_tox_weechat_chat *chat = tox_weechat_get_existing_friend_chat(identity,
|
||||
friend_number);
|
||||
|
||||
char *old_name = tox_weechat_get_name_nt(identity->tox, friend_number);
|
||||
char *new_name = tox_weechat_null_terminate(name, length);
|
||||
|
||||
if (strcmp(old_name, new_name) != 0)
|
||||
{
|
||||
if (chat)
|
||||
{
|
||||
tox_weechat_chat_queue_refresh(chat);
|
||||
|
||||
weechat_printf(chat->buffer,
|
||||
"%s%s is now known as %s",
|
||||
weechat_prefix("network"),
|
||||
old_name, new_name);
|
||||
}
|
||||
|
||||
weechat_printf(identity->buffer,
|
||||
"%s%s is now known as %s",
|
||||
weechat_prefix("network"),
|
||||
old_name, new_name);
|
||||
}
|
||||
|
||||
free(old_name);
|
||||
free(new_name);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_user_status_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
uint8_t status,
|
||||
void *data)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
struct t_tox_weechat_chat *chat = tox_weechat_get_existing_friend_chat(identity,
|
||||
friend_number);
|
||||
if (chat)
|
||||
tox_weechat_chat_queue_refresh(chat);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_status_message_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
struct t_tox_weechat_chat *chat = tox_weechat_get_existing_friend_chat(identity,
|
||||
friend_number);
|
||||
if (chat)
|
||||
tox_weechat_chat_queue_refresh(chat);
|
||||
}
|
||||
|
||||
void
|
||||
tox_weechat_callback_friend_request(Tox *tox,
|
||||
const uint8_t *public_key,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_tox_weechat_identity *identity = data;
|
||||
|
||||
char *message_nt = tox_weechat_null_terminate(message, length);
|
||||
int rc = tox_weechat_friend_request_add(identity, public_key, message_nt);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
char hex_address[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
tox_weechat_bin2hex(public_key, TOX_CLIENT_ID_SIZE, hex_address);
|
||||
weechat_printf(identity->buffer,
|
||||
"%sReceived a friend request from %s: \"%s\"",
|
||||
weechat_prefix("network"),
|
||||
hex_address,
|
||||
message_nt);
|
||||
}
|
||||
else if (rc == -1)
|
||||
{
|
||||
weechat_printf(identity->buffer,
|
||||
"%sReceived a friend request, but your friend request list is full!",
|
||||
weechat_prefix("warning"));
|
||||
}
|
||||
|
||||
free(message_nt);
|
||||
}
|
||||
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_TOX_CALLBACKS_H
|
||||
#define TOX_WEECHAT_TOX_CALLBACKS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
int
|
||||
tox_weechat_do_timer_cb(void *data,
|
||||
int remaining_calls);
|
||||
|
||||
void
|
||||
tox_weechat_friend_message_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
void
|
||||
tox_weechat_friend_action_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
void
|
||||
tox_weechat_connection_status_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
uint8_t status,
|
||||
void *data);
|
||||
|
||||
void
|
||||
tox_weechat_name_change_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *name,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
void
|
||||
tox_weechat_user_status_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
uint8_t status,
|
||||
void *data);
|
||||
|
||||
void
|
||||
tox_weechat_status_message_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
void
|
||||
tox_weechat_callback_friend_request(Tox *tox,
|
||||
const uint8_t *public_key,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
#endif // TOX_WEECHAT_TOX_CALLBACKS_H
|
97
src/twc-bootstrap.c
Normal file
97
src/twc-bootstrap.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc-utils.h"
|
||||
|
||||
#include "twc-bootstrap.h"
|
||||
|
||||
char *twc_bootstrap_addresses[] = {
|
||||
"192.254.75.98",
|
||||
"31.7.57.236",
|
||||
"107.161.17.51",
|
||||
"144.76.60.215",
|
||||
"23.226.230.47",
|
||||
"37.59.102.176",
|
||||
"37.187.46.132",
|
||||
"178.21.112.187",
|
||||
"192.210.149.121",
|
||||
"54.199.139.199",
|
||||
"63.165.243.15",
|
||||
};
|
||||
|
||||
uint16_t twc_bootstrap_ports[] = {
|
||||
33445, 443, 33445, 33445, 33445,
|
||||
33445, 33445, 33445, 33445, 33445,
|
||||
443,
|
||||
};
|
||||
|
||||
char *twc_bootstrap_keys[] = {
|
||||
"951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F",
|
||||
"2A4B50D1D525DA2E669592A20C327B5FAD6C7E5962DC69296F9FEC77C4436E4E",
|
||||
"7BE3951B97CA4B9ECDDA768E8C52BA19E9E2690AB584787BF4C90E04DBB75111",
|
||||
"04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F",
|
||||
"A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074",
|
||||
"B98A2CEAA6C6A2FADC2C3632D284318B60FE5375CCB41EFA081AB67F500C1B0B",
|
||||
"5EB67C51D3FF5A9D528D242B669036ED2A30F8A60E674C45E7D43010CB2E1331",
|
||||
"4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057",
|
||||
"F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67",
|
||||
"7F9C31FE850E97CEFD4C4591DF93FC757C7C12549DDD55F8EEAECC34FE76C029",
|
||||
"8CD087E31C67568103E8C2A28653337E90E6B8EDA0D765D57C6B5172B4F1F04C",
|
||||
};
|
||||
|
||||
int twc_bootstrap_count = sizeof(twc_bootstrap_addresses)
|
||||
/ sizeof(twc_bootstrap_addresses[0]);
|
||||
|
||||
/**
|
||||
* Bootstrap a Tox object with a DHT bootstrap node. Returns the result of
|
||||
* tox_bootstrap_from_address.
|
||||
*/
|
||||
int
|
||||
twc_bootstrap_tox(Tox *tox,
|
||||
const char *address,
|
||||
uint16_t port,
|
||||
const char *public_key)
|
||||
{
|
||||
char binary_key[TOX_FRIEND_ADDRESS_SIZE];
|
||||
twc_hex2bin(public_key, TOX_FRIEND_ADDRESS_SIZE, binary_key);
|
||||
|
||||
int result = tox_bootstrap_from_address(tox,
|
||||
address,
|
||||
port,
|
||||
(uint8_t *)binary_key);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap a Tox object with a random DHT bootstrap node.
|
||||
*/
|
||||
void
|
||||
twc_bootstrap_random_node(Tox *tox)
|
||||
{
|
||||
int i = rand() % twc_bootstrap_count;
|
||||
twc_bootstrap_tox(tox, twc_bootstrap_addresses[i],
|
||||
twc_bootstrap_ports[i],
|
||||
twc_bootstrap_keys[i]);
|
||||
}
|
||||
|
35
src/twc-bootstrap.h
Normal file
35
src/twc-bootstrap.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_BOOTSTRAP_H
|
||||
#define TOX_WEECHAT_BOOTSTRAP_H
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
int
|
||||
twc_bootstrap_tox(Tox *tox,
|
||||
const char *address,
|
||||
uint16_t port,
|
||||
const char *public_key);
|
||||
|
||||
void
|
||||
twc_bootstrap_random_node(Tox *tox);
|
||||
|
||||
#endif // TOX_WEECHAT_BOOTSTRAP_H
|
||||
|
261
src/twc-chat.c
Normal file
261
src/twc-chat.c
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-profile.h"
|
||||
#include "twc-message-queue.h"
|
||||
#include "twc-list.h"
|
||||
#include "twc-utils.h"
|
||||
|
||||
#include "twc-chat.h"
|
||||
|
||||
const char *twc_tag_unsent_message = "tox_unsent";
|
||||
const char *twc_tag_sent_message = "tox_sent";
|
||||
const char *twc_tag_received_message = "tox_received";
|
||||
|
||||
int
|
||||
twc_chat_buffer_input_callback(void *data,
|
||||
struct t_gui_buffer *weechat_buffer,
|
||||
const char *input_data);
|
||||
int
|
||||
twc_chat_buffer_close_callback(void *data,
|
||||
struct t_gui_buffer *weechat_buffer);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new friend chat.
|
||||
*/
|
||||
struct t_twc_chat *
|
||||
twc_chat_new_friend(struct t_twc_profile *profile,
|
||||
int32_t friend_number)
|
||||
{
|
||||
struct t_twc_chat *chat = malloc(sizeof(struct t_twc_chat));
|
||||
if (!chat)
|
||||
return NULL;
|
||||
|
||||
chat->friend_number = friend_number;
|
||||
chat->profile = profile;
|
||||
|
||||
uint8_t client_id[TOX_CLIENT_ID_SIZE];
|
||||
tox_get_client_id(profile->tox, friend_number, client_id);
|
||||
|
||||
// TODO: prepend profile name
|
||||
char buffer_name[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
twc_bin2hex(client_id, TOX_CLIENT_ID_SIZE, buffer_name);
|
||||
|
||||
chat->buffer = weechat_buffer_new(buffer_name,
|
||||
twc_chat_buffer_input_callback, chat,
|
||||
twc_chat_buffer_close_callback, chat);
|
||||
|
||||
if (!(chat->buffer))
|
||||
{
|
||||
free(chat);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
twc_chat_queue_refresh(chat);
|
||||
twc_list_item_new_data_add(profile->chats, chat);
|
||||
|
||||
return chat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh a chat. Updates buffer short_name and title.
|
||||
*/
|
||||
void
|
||||
twc_chat_refresh(struct t_twc_chat *chat)
|
||||
{
|
||||
char *name = twc_get_name_nt(chat->profile->tox,
|
||||
chat->friend_number);
|
||||
char *status_message = twc_get_status_message_nt(chat->profile->tox,
|
||||
chat->friend_number);
|
||||
|
||||
weechat_buffer_set(chat->buffer, "short_name", name);
|
||||
weechat_buffer_set(chat->buffer, "title", status_message);
|
||||
|
||||
free(name);
|
||||
free(status_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twc_chat_queue_refresh. Simply calls twc_chat_refresh.
|
||||
*/
|
||||
int
|
||||
twc_chat_refresh_timer_callback(void *data, int remaining)
|
||||
{
|
||||
twc_chat_refresh(data);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a refresh of the buffer in 1ms (i.e. the next event loop tick). Done
|
||||
* this way to allow data to update before refreshing interface.
|
||||
*/
|
||||
void
|
||||
twc_chat_queue_refresh(struct t_twc_chat *chat)
|
||||
{
|
||||
weechat_hook_timer(1, 0, 1,
|
||||
twc_chat_refresh_timer_callback, chat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an existing chat object for a friend, and if not found, optionally
|
||||
* create a new one.
|
||||
*/
|
||||
struct t_twc_chat *
|
||||
twc_chat_search_friend(struct t_twc_profile *profile,
|
||||
int32_t friend_number,
|
||||
bool create_new)
|
||||
{
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(profile->chats, index, item)
|
||||
{
|
||||
if (item->chat->friend_number == friend_number)
|
||||
return item->chat;
|
||||
}
|
||||
|
||||
if (create_new)
|
||||
{
|
||||
return twc_chat_new_friend(profile, friend_number);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the chat object associated with a buffer, if it exists.
|
||||
*/
|
||||
struct t_twc_chat *
|
||||
twc_chat_search_buffer(struct t_gui_buffer *buffer)
|
||||
{
|
||||
size_t profile_index;
|
||||
struct t_twc_list_item *profile_item;
|
||||
twc_list_foreach(twc_profiles, profile_index, profile_item)
|
||||
{
|
||||
size_t chat_index;
|
||||
struct t_twc_list_item *chat_item;
|
||||
twc_list_foreach(profile_item->profile->chats, chat_index, chat_item)
|
||||
{
|
||||
if (chat_item->chat->buffer == buffer)
|
||||
{
|
||||
return chat_item->chat;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a chat message to a chat's buffer.
|
||||
*/
|
||||
void
|
||||
twc_chat_print_message(struct t_twc_chat *chat,
|
||||
const char *tags,
|
||||
const char *sender,
|
||||
const char *message,
|
||||
enum TWC_MESSAGE_TYPE message_type)
|
||||
{
|
||||
switch (message_type)
|
||||
{
|
||||
case TWC_MESSAGE_TYPE_MESSAGE:
|
||||
weechat_printf_tags(chat->buffer, tags,
|
||||
"%s\t%s",
|
||||
sender, message);
|
||||
break;
|
||||
case TWC_MESSAGE_TYPE_ACTION:
|
||||
weechat_printf_tags(chat->buffer, tags,
|
||||
"%s%s %s",
|
||||
weechat_prefix("action"),
|
||||
sender, message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to the recipient(s) of a chat.
|
||||
*/
|
||||
void
|
||||
twc_chat_send_message(struct t_twc_chat *chat,
|
||||
const char *message,
|
||||
enum TWC_MESSAGE_TYPE message_type)
|
||||
{
|
||||
twc_message_queue_add_friend_message(chat->profile,
|
||||
chat->friend_number,
|
||||
message, message_type);
|
||||
|
||||
char *name = twc_get_self_name_nt(chat->profile->tox);
|
||||
twc_chat_print_message(chat, "", name, message, message_type);
|
||||
free(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for a buffer receiving user input.
|
||||
*/
|
||||
int
|
||||
twc_chat_buffer_input_callback(void *data,
|
||||
struct t_gui_buffer *weechat_buffer,
|
||||
const char *input_data)
|
||||
{
|
||||
struct t_twc_chat *chat = data;
|
||||
twc_chat_send_message(chat, input_data, TWC_MESSAGE_TYPE_MESSAGE);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for a buffer being closed.
|
||||
*/
|
||||
int
|
||||
twc_chat_buffer_close_callback(void *data,
|
||||
struct t_gui_buffer *weechat_buffer)
|
||||
{
|
||||
struct t_twc_chat *chat = data;
|
||||
|
||||
twc_list_remove_with_data(chat->profile->chats, chat);
|
||||
|
||||
free(chat);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all chats connected to a profile.
|
||||
*/
|
||||
void
|
||||
twc_chat_free_profile(struct t_twc_profile *profile)
|
||||
{
|
||||
struct t_twc_chat *chat;
|
||||
while ((chat = twc_list_pop(profile->chats)))
|
||||
{
|
||||
weechat_buffer_set_pointer(chat->buffer, "close_callback", NULL);
|
||||
weechat_buffer_close(chat->buffer);
|
||||
free(chat);
|
||||
}
|
||||
|
||||
free(profile->chats);
|
||||
}
|
||||
|
72
src/twc-chat.h
Normal file
72
src/twc-chat.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_CHAT_H
|
||||
#define TOX_WEECHAT_CHAT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern const char *twc_tag_unsent_message;
|
||||
extern const char *twc_tag_sent_message;
|
||||
extern const char *twc_tag_received_message;
|
||||
|
||||
enum TWC_MESSAGE_TYPE
|
||||
{
|
||||
TWC_MESSAGE_TYPE_MESSAGE,
|
||||
TWC_MESSAGE_TYPE_ACTION,
|
||||
};
|
||||
|
||||
struct t_twc_chat
|
||||
{
|
||||
struct t_twc_profile *profile;
|
||||
|
||||
struct t_gui_buffer *buffer;
|
||||
int32_t friend_number;
|
||||
|
||||
};
|
||||
|
||||
struct t_twc_chat *
|
||||
twc_chat_search_friend(struct t_twc_profile *profile,
|
||||
int32_t friend_number,
|
||||
bool create_new);
|
||||
|
||||
struct t_twc_chat *
|
||||
twc_chat_search_buffer(struct t_gui_buffer *target_buffer);
|
||||
|
||||
void
|
||||
twc_chat_print_message(struct t_twc_chat *chat,
|
||||
const char *tags,
|
||||
const char *sender,
|
||||
const char *message,
|
||||
enum TWC_MESSAGE_TYPE message_type);
|
||||
|
||||
void
|
||||
twc_chat_send_message(struct t_twc_chat *chat,
|
||||
const char *message,
|
||||
enum TWC_MESSAGE_TYPE message_type);
|
||||
|
||||
void
|
||||
twc_chat_queue_refresh(struct t_twc_chat *chat);
|
||||
|
||||
void
|
||||
twc_chat_free_profile(struct t_twc_profile *profile);
|
||||
|
||||
#endif // TOX_WEECHAT_CHAT_H
|
||||
|
781
src/twc-commands.c
Normal file
781
src/twc-commands.c
Normal file
@ -0,0 +1,781 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-utils.h"
|
||||
#include "twc-profile.h"
|
||||
#include "twc-chat.h"
|
||||
#include "twc-friend-request.h"
|
||||
#include "twc-bootstrap.h"
|
||||
#include "twc-list.h"
|
||||
|
||||
#include "twc-commands.h"
|
||||
|
||||
/**
|
||||
* 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; \
|
||||
} \
|
||||
|
||||
/**
|
||||
* 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; \
|
||||
}
|
||||
|
||||
/**
|
||||
* 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; \
|
||||
}
|
||||
|
||||
/**
|
||||
* 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; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /bootstrap callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_bootstrap(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
TWC_CHECK_PROFILE(profile);
|
||||
TWC_CHECK_PROFILE_LOADED(profile);
|
||||
|
||||
// /bootstrap connect <address> <port> <key>
|
||||
if (argc == 5 && weechat_strcasecmp(argv[1], "connect") == 0)
|
||||
{
|
||||
char *address = argv[2];
|
||||
uint16_t port = atoi(argv[3]);
|
||||
char *public_key = argv[4];
|
||||
|
||||
if (!twc_bootstrap_tox(profile->tox, address, port, public_key))
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sBootstrap could not open address \"%s\"",
|
||||
weechat_prefix("error"), address);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /friend callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_friend(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
TWC_CHECK_PROFILE(profile);
|
||||
TWC_CHECK_PROFILE_LOADED(profile);
|
||||
|
||||
// /friend or /friend list
|
||||
if (argc == 1 || (argc == 2 && weechat_strcasecmp(argv[1], "list") == 0))
|
||||
{
|
||||
size_t friend_count = tox_count_friendlist(profile->tox);
|
||||
int32_t friend_numbers[friend_count];
|
||||
tox_get_friendlist(profile->tox, friend_numbers, friend_count);
|
||||
|
||||
if (friend_count == 0)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sYou have no friends :(",
|
||||
weechat_prefix("network"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%s[#] Name [Tox ID (short)]",
|
||||
weechat_prefix("network"));
|
||||
|
||||
for (size_t i = 0; i < friend_count; ++i)
|
||||
{
|
||||
int32_t friend_number = friend_numbers[i];
|
||||
char *name = twc_get_name_nt(profile->tox, friend_number);
|
||||
char *hex_address = twc_get_friend_id_short(profile->tox,
|
||||
friend_number);
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%s[%d] %s [%s]",
|
||||
weechat_prefix("network"),
|
||||
friend_number, name, hex_address);
|
||||
|
||||
free(name);
|
||||
free(hex_address);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
// /friend add <Tox ID> [<message>]
|
||||
else if (argc >= 3 && weechat_strcasecmp(argv[1], "add") == 0)
|
||||
{
|
||||
if (strlen(argv[2]) != TOX_FRIEND_ADDRESS_SIZE * 2)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sTox ID length invalid. Please try again.",
|
||||
weechat_prefix("error"));
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
char address[TOX_FRIEND_ADDRESS_SIZE];
|
||||
twc_hex2bin(argv[2], TOX_FRIEND_ADDRESS_SIZE, address);
|
||||
|
||||
char *message;
|
||||
if (argc == 3 || strlen(argv_eol[3]) == 0)
|
||||
// TODO: default message as option
|
||||
message = "Hi! Please add me on Tox!";
|
||||
else
|
||||
message = argv_eol[3];
|
||||
|
||||
int32_t result = tox_add_friend(profile->tox,
|
||||
(uint8_t *)address,
|
||||
(uint8_t *)message,
|
||||
strlen(message));
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case TOX_FAERR_TOOLONG:
|
||||
weechat_printf(profile->buffer,
|
||||
"%sFriend request message too long! Try again.",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_ALREADYSENT:
|
||||
weechat_printf(profile->buffer,
|
||||
"%sYou have already sent a friend request to that address.",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_OWNKEY:
|
||||
weechat_printf(profile->buffer,
|
||||
"%sYou can't add yourself as a friend.",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_BADCHECKSUM:
|
||||
weechat_printf(profile->buffer,
|
||||
"%sInvalid friend address - try again.",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_NOMEM:
|
||||
weechat_printf(profile->buffer,
|
||||
"%sCould not add friend (out of memory).",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
case TOX_FAERR_UNKNOWN:
|
||||
case TOX_FAERR_SETNEWNOSPAM:
|
||||
case TOX_FAERR_NOMESSAGE:
|
||||
weechat_printf(profile->buffer,
|
||||
"%sCould not add friend (unknown error).",
|
||||
weechat_prefix("error"));
|
||||
break;
|
||||
default:
|
||||
weechat_printf(profile->buffer,
|
||||
"%sFriend request sent!",
|
||||
weechat_prefix("network"));
|
||||
break;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
// /friend remove <number>
|
||||
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;
|
||||
}
|
||||
|
||||
char *name = twc_get_name_nt(profile->tox, friend_number);
|
||||
if (tox_del_friend(profile->tox, friend_number) == 0)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sRemoved %s from friend list.",
|
||||
weechat_prefix("network"), name);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sCould not remove friend!",
|
||||
weechat_prefix("error"));
|
||||
}
|
||||
|
||||
free(name);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
// friend accept|decline <number>|all
|
||||
else if (argc == 3 &&
|
||||
(weechat_strcasecmp(argv[1], "accept") == 0
|
||||
|| weechat_strcasecmp(argv[1], "decline") == 0))
|
||||
{
|
||||
int accept = weechat_strcasecmp(argv[1], "accept") == 0;
|
||||
|
||||
struct t_twc_friend_request *request;
|
||||
if (weechat_strcasecmp(argv[2], "all") == 0)
|
||||
{
|
||||
int count = 0;
|
||||
while ((request = twc_friend_request_with_index(profile, 0)) != NULL)
|
||||
{
|
||||
if (accept)
|
||||
twc_friend_request_accept(request);
|
||||
else
|
||||
twc_friend_request_remove(request);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s %d friend requests.",
|
||||
weechat_prefix("network"),
|
||||
accept ? "Accepted" : "Declined",
|
||||
count);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *endptr;
|
||||
unsigned long num = strtoul(argv[2], &endptr, 10);
|
||||
if (endptr == argv[2] || (request = twc_friend_request_with_index(profile, num)) == NULL)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sInvalid friend request ID.",
|
||||
weechat_prefix("error"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
char hex_address[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
twc_bin2hex(request->tox_id,
|
||||
TOX_CLIENT_ID_SIZE,
|
||||
hex_address);
|
||||
|
||||
if (accept)
|
||||
twc_friend_request_accept(request);
|
||||
else
|
||||
twc_friend_request_remove(request);
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s friend request from %s.",
|
||||
weechat_prefix("network"),
|
||||
accept ? "Accepted" : "Declined",
|
||||
hex_address);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// /friend requests
|
||||
else if (argc == 2 && weechat_strcasecmp(argv[1], "requests") == 0)
|
||||
{
|
||||
if (profile->friend_requests == NULL)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sNo pending friend requests :(",
|
||||
weechat_prefix("network"));
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sPending friend requests:",
|
||||
weechat_prefix("network"));
|
||||
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(profile->friend_requests, index, item)
|
||||
{
|
||||
// TODO: load short form address length from config
|
||||
char hex_address[12 + 1];
|
||||
twc_bin2hex(item->friend_request->tox_id,
|
||||
6,
|
||||
hex_address);
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%s[%d] Address: %s\n"
|
||||
"[%d] Message: %s",
|
||||
weechat_prefix("network"),
|
||||
index, hex_address,
|
||||
index, item->friend_request->message);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /me callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_me(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc == 1)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
struct t_twc_chat *chat = twc_chat_search_buffer(buffer);
|
||||
TWC_CHECK_CHAT(chat);
|
||||
TWC_CHECK_PROFILE_LOADED(chat->profile);
|
||||
|
||||
twc_chat_send_message(chat, argv_eol[1], TWC_MESSAGE_TYPE_ACTION);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /msg callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_msg(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc == 1)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
TWC_CHECK_PROFILE(profile);
|
||||
TWC_CHECK_PROFILE_LOADED(profile);
|
||||
|
||||
char *endptr;
|
||||
unsigned long friend_number = strtoul(argv[1], &endptr, 10);
|
||||
|
||||
if (endptr == argv[1] || !tox_friend_exists(profile->tox, friend_number))
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sInvalid friend number.",
|
||||
weechat_prefix("error"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /myid callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_myid(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
TWC_CHECK_PROFILE(profile);
|
||||
TWC_CHECK_PROFILE_LOADED(profile);
|
||||
|
||||
uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(profile->tox, address);
|
||||
|
||||
char address_str[TOX_FRIEND_ADDRESS_SIZE * 2 + 1];
|
||||
twc_bin2hex(address, TOX_FRIEND_ADDRESS_SIZE, address_str);
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%sYour Tox address: %s",
|
||||
weechat_prefix("network"),
|
||||
address_str);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /name callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_name(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc == 1)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
TWC_CHECK_PROFILE(profile);
|
||||
TWC_CHECK_PROFILE_LOADED(profile);
|
||||
|
||||
char *name = argv_eol[1];
|
||||
|
||||
int result = tox_set_name(profile->tox, (uint8_t *)name, strlen(name));
|
||||
if (result == -1)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s",
|
||||
weechat_prefix("error"),
|
||||
"Could not change name.");
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
weechat_bar_item_update("input_prompt");
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%sYou are now known as %s",
|
||||
weechat_prefix("network"),
|
||||
name);
|
||||
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(profile->chats, index, item)
|
||||
{
|
||||
weechat_printf(item->chat->buffer,
|
||||
"%sYou are now known as %s",
|
||||
weechat_prefix("network"),
|
||||
name);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /status callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_status(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
if (argc != 2)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
TWC_CHECK_PROFILE(profile);
|
||||
TWC_CHECK_PROFILE_LOADED(profile);
|
||||
|
||||
TOX_USERSTATUS status = TOX_USERSTATUS_INVALID;
|
||||
if (weechat_strcasecmp(argv[1], "online") == 0)
|
||||
status = TOX_USERSTATUS_NONE;
|
||||
else if (weechat_strcasecmp(argv[1], "busy") == 0)
|
||||
status = TOX_USERSTATUS_BUSY;
|
||||
else if (weechat_strcasecmp(argv[1], "away") == 0)
|
||||
status = TOX_USERSTATUS_AWAY;
|
||||
|
||||
if (status == TOX_USERSTATUS_INVALID)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
tox_set_user_status(profile->tox, status);
|
||||
weechat_bar_item_update("away");
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /statusmsg callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_statusmsg(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
TWC_CHECK_PROFILE(profile);
|
||||
TWC_CHECK_PROFILE_LOADED(profile);
|
||||
|
||||
char *message = argc > 1 ? argv_eol[1] : " ";
|
||||
|
||||
int result = tox_set_status_message(profile->tox,
|
||||
(uint8_t *)message,
|
||||
strlen(message));
|
||||
if (result == -1)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s",
|
||||
weechat_prefix("error"),
|
||||
"Could not set status message.");
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command /tox callback.
|
||||
*/
|
||||
int
|
||||
twc_cmd_tox(void *data, struct t_gui_buffer *buffer,
|
||||
int argc, char **argv, char **argv_eol)
|
||||
{
|
||||
// /tox [list]
|
||||
if (argc == 1 || (argc == 2 && weechat_strcasecmp(argv[1], "list") == 0))
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%sAll Tox profiles:",
|
||||
weechat_prefix("network"));
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(twc_profiles, index, item)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s",
|
||||
weechat_prefix("network"),
|
||||
item->profile->name);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
// /tox create
|
||||
else if (argc == 3 && (weechat_strcasecmp(argv[1], "create") == 0))
|
||||
{
|
||||
char *name = argv[2];
|
||||
|
||||
if (twc_profile_search_name(name))
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: profile \"%s\" already exists!",
|
||||
weechat_prefix("error"), weechat_plugin->name,
|
||||
name);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
struct t_twc_profile *profile = twc_profile_new(name);
|
||||
weechat_printf(NULL,
|
||||
"%s%s: profile \"%s\" created!",
|
||||
weechat_prefix("network"), weechat_plugin->name,
|
||||
profile->name);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
// /tox delete
|
||||
else if ((argc == 3 || argc == 4)
|
||||
&& (weechat_strcasecmp(argv[1], "delete") == 0))
|
||||
{
|
||||
char *name = argv[2];
|
||||
char *flag = argv[3];
|
||||
|
||||
struct t_twc_profile *profile = twc_profile_search_name(name);
|
||||
TWC_CHECK_PROFILE_EXISTS(profile);
|
||||
|
||||
if (argc == 4 && strcmp(flag, "-keepdata") == 0)
|
||||
{
|
||||
twc_profile_delete(profile, false);
|
||||
}
|
||||
else if (argc == 4 && strcmp(flag, "-yes") == 0)
|
||||
{
|
||||
twc_profile_delete(profile, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: You must confirm deletion with either "
|
||||
"\"-keepdata\" or \"-yes\" (see /help tox)",
|
||||
weechat_prefix("error"), weechat_plugin->name);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
weechat_printf(NULL,
|
||||
"%s%s: profile \"%s\" has been deleted.",
|
||||
weechat_prefix("error"), weechat_plugin->name,
|
||||
name);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
// /tox load <profile>
|
||||
else if (argc >= 2 && (weechat_strcasecmp(argv[1], "load") == 0))
|
||||
{
|
||||
if (argc == 2)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
if (!profile)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
twc_profile_load(profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 2; i < argc; ++i)
|
||||
{
|
||||
char *name = argv[i];
|
||||
struct t_twc_profile *profile = twc_profile_search_name(name);
|
||||
TWC_CHECK_PROFILE_EXISTS(profile);
|
||||
|
||||
twc_profile_load(profile);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
// /tox unload <profile>
|
||||
else if (argc >= 2 && (weechat_strcasecmp(argv[1], "unload") == 0))
|
||||
{
|
||||
if (argc == 2)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
if (!profile)
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
twc_profile_unload(profile);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 2; i < argc; ++i)
|
||||
{
|
||||
char *name = argv[i];
|
||||
struct t_twc_profile *profile = twc_profile_search_name(name);
|
||||
TWC_CHECK_PROFILE_EXISTS(profile);
|
||||
|
||||
twc_profile_unload(profile);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
return WEECHAT_RC_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Tox-WeeChat commands.
|
||||
*/
|
||||
void
|
||||
twc_commands_init()
|
||||
{
|
||||
weechat_hook_command("bootstrap",
|
||||
"manage bootstrap nodes",
|
||||
"connect <address> <port> <Tox ID>",
|
||||
"address: internet address of node to bootstrap with\n"
|
||||
" port: port of the node\n"
|
||||
" Tox ID: Tox ID of the node",
|
||||
NULL, twc_cmd_bootstrap, NULL);
|
||||
|
||||
weechat_hook_command("friend",
|
||||
"manage friends",
|
||||
"list"
|
||||
" || add <address> [<message>]"
|
||||
" || remove <number>"
|
||||
" || requests"
|
||||
" || accept <number>|all"
|
||||
" || decline <number>|all",
|
||||
" list: list all friends\n"
|
||||
" add: add a friend by their public Tox address\n"
|
||||
"requests: list friend requests\n"
|
||||
" accept: accept friend requests\n"
|
||||
" decline: decline friend requests\n",
|
||||
NULL, twc_cmd_friend, NULL);
|
||||
|
||||
weechat_hook_command("me",
|
||||
"send an action to the current chat",
|
||||
"<message>",
|
||||
"message: message to send",
|
||||
NULL, twc_cmd_me, NULL);
|
||||
|
||||
weechat_hook_command("msg",
|
||||
"send a message to a Tox friend",
|
||||
"<id> [<message>]",
|
||||
" id: friend number of the person to message\n"
|
||||
"message: message to send",
|
||||
NULL, twc_cmd_msg, NULL);
|
||||
|
||||
weechat_hook_command("myid",
|
||||
"get your Tox ID to give to friends",
|
||||
"", "",
|
||||
NULL, twc_cmd_myid, NULL);
|
||||
|
||||
weechat_hook_command("name",
|
||||
"change your Tox name",
|
||||
"<name>",
|
||||
"name: your new name",
|
||||
NULL, twc_cmd_name, NULL);
|
||||
|
||||
weechat_hook_command("status",
|
||||
"change your Tox status",
|
||||
"online|busy|away",
|
||||
"",
|
||||
NULL, twc_cmd_status, NULL);
|
||||
|
||||
weechat_hook_command("statusmsg",
|
||||
"change your Tox status message",
|
||||
"[<message>]",
|
||||
"message: your new status message",
|
||||
NULL, twc_cmd_statusmsg, NULL);
|
||||
|
||||
weechat_hook_command("tox",
|
||||
"manage Tox profiles",
|
||||
"list"
|
||||
" || create <name>"
|
||||
" || delete <name> -yes|-keepdata"
|
||||
" || load [<name>...]"
|
||||
" || unload [<name>...]",
|
||||
" list: list all Tox profile\n"
|
||||
"create: create a new Tox profile\n"
|
||||
"delete: delete a Tox profile; requires either -yes "
|
||||
"to confirm deletion or -keepdata to delete the "
|
||||
"profile but keep the Tox data file\n"
|
||||
" load: load a Tox profile and connect to the network\n"
|
||||
"unload: unload a Tox profile\n",
|
||||
"list"
|
||||
" || create"
|
||||
" || delete %(tox_profiles) -yes|-keepdata"
|
||||
" || load %(tox_unloaded_profiles)|%*"
|
||||
" || unload %(tox_loaded_profiles)|%*",
|
||||
twc_cmd_tox, NULL);
|
||||
}
|
||||
|
@ -20,9 +20,7 @@
|
||||
#ifndef TOX_WEECHAT_COMMANDS_H
|
||||
#define TOX_WEECHAT_COMMANDS_H
|
||||
|
||||
/**
|
||||
* Register command callbacks.
|
||||
*/
|
||||
void tox_weechat_commands_init();
|
||||
void twc_commands_init();
|
||||
|
||||
#endif // TOX_WEECHAT_COMMANDS_H
|
||||
|
83
src/twc-completion.c
Normal file
83
src/twc-completion.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-profile.h"
|
||||
#include "twc-list.h"
|
||||
|
||||
#include "twc-completion.h"
|
||||
|
||||
enum
|
||||
{
|
||||
TWC_ALL_PROFILES,
|
||||
TWC_LOADED_PROFILES,
|
||||
TWC_UNLOADED_PROFILES,
|
||||
};
|
||||
|
||||
/**
|
||||
* Complete a profile name, possibly filtering by loaded/unloaded profiles.
|
||||
*/
|
||||
int
|
||||
twc_completion_profile(void *data,
|
||||
const char *completion_item,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_gui_completion *completion)
|
||||
{
|
||||
int flag = (int)(intptr_t)data;
|
||||
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(twc_profiles, index, item)
|
||||
{
|
||||
if (flag == TWC_ALL_PROFILES
|
||||
|| (flag == TWC_LOADED_PROFILES && item->profile->tox != NULL)
|
||||
|| (flag == TWC_UNLOADED_PROFILES && item->profile->tox == NULL))
|
||||
{
|
||||
weechat_hook_completion_list_add(completion,
|
||||
item->profile->name,
|
||||
0,
|
||||
WEECHAT_LIST_POS_SORT);
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
void
|
||||
twc_completion_init()
|
||||
{
|
||||
weechat_hook_completion("tox_profiles",
|
||||
"profile",
|
||||
twc_completion_profile,
|
||||
(void *)(intptr_t)TWC_ALL_PROFILES);
|
||||
weechat_hook_completion("tox_loaded_profiles",
|
||||
"profile",
|
||||
twc_completion_profile,
|
||||
(void *)(intptr_t)TWC_LOADED_PROFILES);
|
||||
weechat_hook_completion("tox_unloaded_profiles",
|
||||
"profile",
|
||||
twc_completion_profile,
|
||||
(void *)(intptr_t)TWC_UNLOADED_PROFILES);
|
||||
}
|
||||
|
27
src/twc-completion.h
Normal file
27
src/twc-completion.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_COMPLETION_H
|
||||
#define TOX_WEECHAT_COMPLETION_H
|
||||
|
||||
void
|
||||
twc_completion_init();
|
||||
|
||||
#endif // TOX_WEECHAT_COMPLETION_H
|
||||
|
288
src/twc-config.c
Normal file
288
src/twc-config.c
Normal file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-list.h"
|
||||
#include "twc-profile.h"
|
||||
|
||||
#include "twc-config.h"
|
||||
|
||||
struct t_config_file *twc_config_file = NULL;
|
||||
struct t_config_section *twc_config_section_profile = NULL;
|
||||
|
||||
char *twc_profile_option_names[TWC_PROFILE_NUM_OPTIONS] =
|
||||
{
|
||||
"save_file",
|
||||
"autoload",
|
||||
"max_friend_requests",
|
||||
};
|
||||
|
||||
char *twc_profile_option_defaults[TWC_PROFILE_NUM_OPTIONS] =
|
||||
{
|
||||
"%h/tox/%p",
|
||||
"off",
|
||||
"100",
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the index of a profile option name.
|
||||
*/
|
||||
int
|
||||
twc_config_profile_option_search(const char *option_name)
|
||||
{
|
||||
for (int i = 0; i < TWC_PROFILE_NUM_OPTIONS; ++i)
|
||||
{
|
||||
if (strcmp(twc_profile_option_names[i], option_name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a profile option is read.
|
||||
*/
|
||||
int
|
||||
twc_config_profile_read_callback(void *data,
|
||||
struct t_config_file *config_file,
|
||||
struct t_config_section *section,
|
||||
const char *option_name,
|
||||
const char *value)
|
||||
{
|
||||
int rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
|
||||
|
||||
if (option_name)
|
||||
{
|
||||
char *dot_pos = strrchr(option_name, '.');
|
||||
if (dot_pos)
|
||||
{
|
||||
char *profile_name = weechat_strndup(option_name,
|
||||
dot_pos-option_name);
|
||||
char *option_name = dot_pos + 1;
|
||||
if (profile_name)
|
||||
{
|
||||
int option_index = twc_config_profile_option_search(option_name);
|
||||
if (option_index >= 0)
|
||||
{
|
||||
struct t_twc_profile *profile =
|
||||
twc_profile_search_name(profile_name);
|
||||
|
||||
if (!profile)
|
||||
profile = twc_profile_new(profile_name);
|
||||
|
||||
if (profile)
|
||||
{
|
||||
rc = weechat_config_option_set(profile->options[option_index],
|
||||
value, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: error creating profile \"%s\"",
|
||||
weechat_prefix("error"),
|
||||
weechat_plugin->name,
|
||||
profile_name);
|
||||
}
|
||||
}
|
||||
|
||||
free(profile_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == WEECHAT_CONFIG_OPTION_SET_ERROR)
|
||||
{
|
||||
weechat_printf(NULL,
|
||||
"%s%s: error creating profile option \"%s\"",
|
||||
weechat_prefix("error"), weechat_plugin->name,
|
||||
option_name);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when profile options should be written.
|
||||
*/
|
||||
int
|
||||
twc_config_profile_write_callback(void *data,
|
||||
struct t_config_file *config_file,
|
||||
const char *section_name)
|
||||
{
|
||||
if (!weechat_config_write_line (config_file, section_name, NULL))
|
||||
return WEECHAT_CONFIG_WRITE_ERROR;
|
||||
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(twc_profiles, index, item)
|
||||
{
|
||||
for (int i = 0; i < TWC_PROFILE_NUM_OPTIONS; ++i)
|
||||
{
|
||||
if (!weechat_config_write_option(twc_config_file,
|
||||
item->profile->options[i]))
|
||||
{
|
||||
return WEECHAT_CONFIG_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WEECHAT_CONFIG_WRITE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for checking an option value being set for a profile.
|
||||
*/
|
||||
int
|
||||
twc_config_profile_check_value_callback(void *data,
|
||||
struct t_config_option *option,
|
||||
const char *value)
|
||||
{
|
||||
return 1; // 1=ok, 0=not ok
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for option being changed for a profile.
|
||||
*/
|
||||
void
|
||||
twc_config_profile_change_callback(void *data,
|
||||
struct t_config_option *option)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Tox-WeeChat config. Creates file and section objects.
|
||||
*/
|
||||
void
|
||||
twc_config_init()
|
||||
{
|
||||
twc_config_file = weechat_config_new("tox", NULL, NULL);
|
||||
|
||||
twc_config_section_profile =
|
||||
weechat_config_new_section(twc_config_file, "profile",
|
||||
0, 0,
|
||||
twc_config_profile_read_callback, NULL,
|
||||
twc_config_profile_write_callback, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new option for a profile.
|
||||
*/
|
||||
struct t_config_option *
|
||||
twc_config_init_option(int option_index, const char *option_name)
|
||||
{
|
||||
switch (option_index)
|
||||
{
|
||||
case TWC_PROFILE_OPTION_AUTOLOAD:
|
||||
return weechat_config_new_option(
|
||||
twc_config_file, twc_config_section_profile,
|
||||
option_name, "boolean",
|
||||
"automatically load a profile and connect to the Tox network "
|
||||
"when WeeChat starts",
|
||||
NULL, 0, 0,
|
||||
twc_profile_option_defaults[option_index],
|
||||
NULL,
|
||||
0,
|
||||
twc_config_profile_check_value_callback, NULL,
|
||||
twc_config_profile_change_callback, NULL,
|
||||
NULL, NULL);
|
||||
case TWC_PROFILE_OPTION_MAX_FRIEND_REQUESTS:
|
||||
return weechat_config_new_option(
|
||||
twc_config_file, twc_config_section_profile,
|
||||
option_name, "integer",
|
||||
"maximum amount of friend requests to retain before dropping "
|
||||
"new ones",
|
||||
NULL, 0, INT_MAX,
|
||||
twc_profile_option_defaults[option_index],
|
||||
NULL,
|
||||
0,
|
||||
twc_config_profile_check_value_callback, NULL,
|
||||
twc_config_profile_change_callback, NULL,
|
||||
NULL, NULL);
|
||||
case TWC_PROFILE_OPTION_SAVEFILE:
|
||||
return weechat_config_new_option(
|
||||
twc_config_file, twc_config_section_profile,
|
||||
option_name, "string",
|
||||
"path to Tox data file (\"%h\" will be replaced by WeeChat "
|
||||
"home, \"%p\" by the profile name); will be created if it does "
|
||||
"not exist.",
|
||||
NULL, 0, 0,
|
||||
twc_profile_option_defaults[option_index],
|
||||
NULL,
|
||||
0,
|
||||
twc_config_profile_check_value_callback, NULL,
|
||||
twc_config_profile_change_callback, NULL,
|
||||
NULL, NULL);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize options for a given profile.
|
||||
*/
|
||||
void
|
||||
twc_config_init_profile(struct t_twc_profile *profile)
|
||||
{
|
||||
for (int i = 0; i < TWC_PROFILE_NUM_OPTIONS; ++i)
|
||||
{
|
||||
// length: name + . + option + \0
|
||||
size_t length = strlen(profile->name) + 1
|
||||
+ strlen(twc_profile_option_names[i]) + 1;
|
||||
|
||||
char *option_name = malloc(sizeof(*option_name) * length);
|
||||
if (option_name)
|
||||
{
|
||||
snprintf(option_name, length, "%s.%s",
|
||||
profile->name,
|
||||
twc_profile_option_names[i]);
|
||||
|
||||
profile->options[i] = twc_config_init_option(i, option_name);
|
||||
free (option_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read config data from file, creating profile objects for stored profiles.
|
||||
*/
|
||||
int
|
||||
twc_config_read()
|
||||
{
|
||||
return weechat_config_read(twc_config_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write config data to disk.
|
||||
*/
|
||||
int
|
||||
twc_config_write()
|
||||
{
|
||||
return weechat_config_write(twc_config_file);
|
||||
}
|
||||
|
@ -20,21 +20,19 @@
|
||||
#ifndef TOX_WEECHAT_CONFIG_H
|
||||
#define TOX_WEECHAT_CONFIG_H
|
||||
|
||||
#include "tox-weechat-identities.h"
|
||||
|
||||
extern struct t_config_file *tox_weechat_config_file;
|
||||
extern struct t_config_section *tox_weechat_config_section_identity;
|
||||
#include "twc-profile.h"
|
||||
|
||||
void
|
||||
tox_weechat_config_init();
|
||||
twc_config_init();
|
||||
|
||||
int
|
||||
tox_weechat_config_read();
|
||||
twc_config_read();
|
||||
|
||||
int
|
||||
tox_weechat_config_write();
|
||||
twc_config_write();
|
||||
|
||||
void
|
||||
tox_weechat_config_init_identity(struct t_tox_weechat_identity *identity);
|
||||
twc_config_init_profile(struct t_twc_profile *profile);
|
||||
|
||||
#endif // TOX_WEECHAT_CONFIG_H
|
||||
|
19
src/twc-data.c
Normal file
19
src/twc-data.c
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
@ -20,21 +20,5 @@
|
||||
#ifndef TOX_WEECHAT_DATA_H
|
||||
#define TOX_WEECHAT_DATA_H
|
||||
|
||||
struct t_tox_weechat_identity;
|
||||
|
||||
void
|
||||
tox_weechat_data_load();
|
||||
|
||||
void
|
||||
tox_weechat_data_identity_save(struct t_tox_weechat_identity *identity);
|
||||
|
||||
void
|
||||
tox_weechat_data_identity_load(struct t_tox_weechat_identity *identity);
|
||||
|
||||
int
|
||||
tox_weechat_data_save();
|
||||
|
||||
void
|
||||
tox_weechat_data_free();
|
||||
|
||||
#endif // TOX_WEECHAT_DATA_H
|
||||
|
125
src/twc-friend-request.c
Normal file
125
src/twc-friend-request.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-profile.h"
|
||||
#include "twc-list.h"
|
||||
#include "twc-utils.h"
|
||||
|
||||
#include "twc-friend-request.h"
|
||||
|
||||
/**
|
||||
* Add a new friend request to an profile.
|
||||
*
|
||||
* Returns 0 on success, -1 on a full friend request list, -2 on other error.
|
||||
*/
|
||||
int
|
||||
twc_friend_request_add(struct t_twc_profile *profile,
|
||||
const uint8_t *client_id,
|
||||
const char *message)
|
||||
{
|
||||
struct t_config_option *option =
|
||||
profile->options[TWC_PROFILE_OPTION_MAX_FRIEND_REQUESTS];
|
||||
unsigned int max_requests = weechat_config_integer(option);
|
||||
|
||||
// check for a full friend request list
|
||||
if (profile->friend_requests->count >= max_requests)
|
||||
return -1;
|
||||
|
||||
// create a new request
|
||||
struct t_twc_friend_request *request
|
||||
= malloc(sizeof(struct t_twc_friend_request));
|
||||
if (!request)
|
||||
return -2;
|
||||
|
||||
request->profile = profile;
|
||||
request->message = strdup(message);
|
||||
memcpy(request->tox_id, client_id, TOX_CLIENT_ID_SIZE);
|
||||
|
||||
// add to list
|
||||
twc_list_item_new_data_add(profile->friend_requests, request);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept a friend request. Remove and free the request.
|
||||
*/
|
||||
void
|
||||
twc_friend_request_accept(struct t_twc_friend_request *request)
|
||||
{
|
||||
tox_add_friend_norequest(request->profile->tox, request->tox_id);
|
||||
twc_friend_request_remove(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and free a friend request from its profile.
|
||||
*/
|
||||
void
|
||||
twc_friend_request_remove(struct t_twc_friend_request *request)
|
||||
{
|
||||
twc_list_remove_with_data(request->profile->friend_requests, request);
|
||||
twc_friend_request_free(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get friend request with a given index.
|
||||
*/
|
||||
struct t_twc_friend_request *
|
||||
twc_friend_request_with_index(struct t_twc_profile *profile,
|
||||
unsigned int index)
|
||||
{
|
||||
struct t_twc_list_item *item = twc_list_get(profile->friend_requests, index);
|
||||
if (item)
|
||||
return item->friend_request;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a friend request.
|
||||
*/
|
||||
void
|
||||
twc_friend_request_free(struct t_twc_friend_request *request)
|
||||
{
|
||||
free(request->message);
|
||||
free(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all friend requests from a profile.
|
||||
*/
|
||||
void
|
||||
twc_friend_request_free_profile(struct t_twc_profile *profile)
|
||||
{
|
||||
struct t_twc_friend_request *request;
|
||||
|
||||
while ((request = twc_list_pop(profile->friend_requests)))
|
||||
twc_friend_request_free(request);
|
||||
|
||||
free(profile->friend_requests);
|
||||
}
|
||||
|
60
src/twc-friend-request.h
Normal file
60
src/twc-friend-request.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_FRIEND_REQUEST_H
|
||||
#define TOX_WEECHAT_FRIEND_REQUEST_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
/**
|
||||
* Represents a friend request with a Tox ID and a message.
|
||||
*/
|
||||
struct t_twc_friend_request
|
||||
{
|
||||
struct t_twc_profile *profile;
|
||||
|
||||
uint8_t tox_id[TOX_CLIENT_ID_SIZE];
|
||||
char *message;
|
||||
};
|
||||
|
||||
int
|
||||
twc_friend_request_add(struct t_twc_profile *profile,
|
||||
const uint8_t *client_id,
|
||||
const char *message);
|
||||
|
||||
void
|
||||
twc_friend_request_accept(struct t_twc_friend_request *request);
|
||||
|
||||
void
|
||||
twc_friend_request_remove(struct t_twc_friend_request *request);
|
||||
|
||||
struct t_twc_friend_request *
|
||||
twc_friend_request_with_index(struct t_twc_profile *profile,
|
||||
unsigned int index);
|
||||
|
||||
void
|
||||
twc_friend_request_free(struct t_twc_friend_request *request);
|
||||
|
||||
void
|
||||
twc_friend_request_free_profile(struct t_twc_profile *profile);
|
||||
|
||||
#endif // TOX_WEECHAT_FRIEND_REQUEST_H
|
||||
|
109
src/twc-gui.c
Normal file
109
src/twc-gui.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or * (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-profile.h"
|
||||
#include "twc-utils.h"
|
||||
|
||||
#include "twc-gui.h"
|
||||
|
||||
char *
|
||||
twc_bar_item_away(void *data,
|
||||
struct t_gui_bar_item *item,
|
||||
struct t_gui_window *window,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_hashtable *extra_info)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
|
||||
if (!profile || !(profile->tox))
|
||||
return NULL;
|
||||
|
||||
char *status = NULL;;
|
||||
switch (tox_get_self_user_status(profile->tox))
|
||||
{
|
||||
case TOX_USERSTATUS_BUSY:
|
||||
status = strdup("busy");
|
||||
break;
|
||||
case TOX_USERSTATUS_AWAY:
|
||||
status = strdup("away");
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
char *
|
||||
twc_bar_item_input_prompt(void *data,
|
||||
struct t_gui_bar_item *item,
|
||||
struct t_gui_window *window,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_hashtable *extra_info)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
|
||||
if (!profile || !(profile->tox))
|
||||
return NULL;
|
||||
|
||||
return twc_get_self_name_nt(profile->tox);
|
||||
}
|
||||
|
||||
char *
|
||||
twc_bar_item_buffer_plugin(void *data, struct t_gui_bar_item *item,
|
||||
struct t_gui_window *window,
|
||||
struct t_gui_buffer *buffer,
|
||||
struct t_hashtable *extra_info)
|
||||
{
|
||||
struct t_twc_profile *profile = twc_profile_search_buffer(buffer);
|
||||
|
||||
char string[256];
|
||||
|
||||
const char *plugin_name = weechat_plugin_get_name(weechat_plugin);
|
||||
|
||||
if (!profile)
|
||||
return strdup(plugin_name);
|
||||
|
||||
const char *profile_name = profile->name;
|
||||
|
||||
snprintf(string, sizeof(string),
|
||||
"%s%s/%s%s%s/%s%s",
|
||||
plugin_name,
|
||||
weechat_color("bar_delim"),
|
||||
weechat_color("bar_fg"),
|
||||
profile_name,
|
||||
weechat_color("bar_delim"),
|
||||
weechat_color("bar_fg"),
|
||||
profile->tox_online ? "online" : "offline");
|
||||
|
||||
return strdup(string);
|
||||
}
|
||||
|
||||
void twc_gui_init()
|
||||
{
|
||||
weechat_bar_item_new("away", twc_bar_item_away, NULL);
|
||||
weechat_bar_item_new("input_prompt", twc_bar_item_input_prompt, NULL);
|
||||
weechat_bar_item_new("buffer_plugin", twc_bar_item_buffer_plugin, NULL);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef TOX_WEECHAT_GUI_H
|
||||
#define TOX_WEECHAT_GUI_H
|
||||
|
||||
void tox_weechat_gui_init();
|
||||
void twc_gui_init();
|
||||
|
||||
#endif // TOX_WEECHAT_GUI_H
|
||||
|
187
src/twc-list.c
Normal file
187
src/twc-list.c
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "twc-list.h"
|
||||
|
||||
/**
|
||||
* Create and return a new list.
|
||||
*/
|
||||
struct t_twc_list *
|
||||
twc_list_new()
|
||||
{
|
||||
struct t_twc_list *list = malloc(sizeof(struct t_twc_list));
|
||||
|
||||
list->head = list->tail = NULL;
|
||||
list->count = 0;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new list item.
|
||||
*/
|
||||
struct t_twc_list_item *
|
||||
twc_list_item_new()
|
||||
{
|
||||
struct t_twc_list_item *item = malloc(sizeof(struct t_twc_list_item));
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new list item with data.
|
||||
*/
|
||||
struct t_twc_list_item *
|
||||
twc_list_item_new_data(const void *data)
|
||||
{
|
||||
struct t_twc_list_item *item = twc_list_item_new();
|
||||
item->data = (void *)data;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new list item, add it to a list and return the item.
|
||||
*/
|
||||
struct t_twc_list_item *
|
||||
twc_list_item_new_add(struct t_twc_list *list)
|
||||
{
|
||||
struct t_twc_list_item *item = twc_list_item_new();
|
||||
twc_list_add(list, item);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new list item with data, add it to a list and return the item.
|
||||
*/
|
||||
struct t_twc_list_item *
|
||||
twc_list_item_new_data_add(struct t_twc_list *list, const void *data)
|
||||
{
|
||||
struct t_twc_list_item *item = twc_list_item_new_data(data);
|
||||
twc_list_add(list, item);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item to the list.
|
||||
*/
|
||||
void
|
||||
twc_list_add(struct t_twc_list *list,
|
||||
struct t_twc_list_item *item)
|
||||
{
|
||||
item->list = list;
|
||||
|
||||
item->prev_item = list->tail;
|
||||
item->next_item = NULL;
|
||||
|
||||
if (list->head == NULL)
|
||||
list->head = item;
|
||||
else
|
||||
list->tail->next_item = item;
|
||||
|
||||
list->tail = item;
|
||||
|
||||
++(list->count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the list it's in. Frees the item, but not the data
|
||||
* associated with it.
|
||||
*
|
||||
* Returns the data of the removed item.
|
||||
*/
|
||||
void *
|
||||
twc_list_remove(struct t_twc_list_item *item)
|
||||
{
|
||||
struct t_twc_list *list = item->list;
|
||||
|
||||
if (item == list->tail)
|
||||
list->tail = item->prev_item;
|
||||
|
||||
if (item->prev_item)
|
||||
item->prev_item->next_item = item->next_item;
|
||||
else
|
||||
list->head = item->next_item;
|
||||
|
||||
if (item->next_item)
|
||||
item->next_item->prev_item = item->prev_item;
|
||||
|
||||
--(list->count);
|
||||
|
||||
void *data = item->data;
|
||||
|
||||
free(item);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item with the given data from the list. Frees the item, but not
|
||||
* the data.
|
||||
*/
|
||||
void
|
||||
twc_list_remove_with_data(struct t_twc_list *list, const void *data)
|
||||
{
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(list, index, item)
|
||||
{
|
||||
if (item->data == data)
|
||||
{
|
||||
twc_list_remove(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the last item from the list. Frees the item, and returns the data
|
||||
* associated with it.
|
||||
*/
|
||||
void *
|
||||
twc_list_pop(struct t_twc_list *list)
|
||||
{
|
||||
if (list->tail)
|
||||
return twc_list_remove(list->tail);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list item at an index, or NULL if it does not exist.
|
||||
*/
|
||||
struct t_twc_list_item *
|
||||
twc_list_get(struct t_twc_list *list, size_t index)
|
||||
{
|
||||
if (index > list->count)
|
||||
return NULL;
|
||||
|
||||
size_t current_index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(list, current_index, item)
|
||||
{
|
||||
if (current_index == index)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
87
src/twc-list.h
Normal file
87
src/twc-list.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_LIST_H
|
||||
#define TOX_WEECHAT_LIST_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct t_twc_list
|
||||
{
|
||||
size_t count;
|
||||
struct t_twc_list_item *head;
|
||||
struct t_twc_list_item *tail;
|
||||
};
|
||||
|
||||
struct t_twc_list_item
|
||||
{
|
||||
struct t_twc_list *list;
|
||||
|
||||
// don't know if this is a good idea
|
||||
// probably not
|
||||
union
|
||||
{
|
||||
void *data;
|
||||
struct t_twc_profile *profile;
|
||||
struct t_twc_friend_request *friend_request;
|
||||
struct t_twc_chat *chat;
|
||||
struct t_twc_queued_message *queued_message;
|
||||
};
|
||||
|
||||
struct t_twc_list_item *next_item;
|
||||
struct t_twc_list_item *prev_item;
|
||||
};
|
||||
|
||||
struct t_twc_list *
|
||||
twc_list_new();
|
||||
|
||||
struct t_twc_list_item *
|
||||
twc_list_item_new();
|
||||
|
||||
struct t_twc_list_item *
|
||||
twc_list_item_new_data(const void *data);
|
||||
|
||||
struct t_twc_list_item *
|
||||
twc_list_item_new_add(struct t_twc_list *list);
|
||||
|
||||
struct t_twc_list_item *
|
||||
twc_list_item_new_data_add(struct t_twc_list *list, const void *data);
|
||||
|
||||
void
|
||||
twc_list_add(struct t_twc_list *list, struct t_twc_list_item *item);
|
||||
|
||||
void *
|
||||
twc_list_remove(struct t_twc_list_item *item);
|
||||
|
||||
void
|
||||
twc_list_remove_with_data(struct t_twc_list *list, const void *data);
|
||||
|
||||
void *
|
||||
twc_list_pop(struct t_twc_list *list);
|
||||
|
||||
struct t_twc_list_item *
|
||||
twc_list_get(struct t_twc_list *list, size_t index);
|
||||
|
||||
#define twc_list_foreach(list, index, item) \
|
||||
for (item = list->head, index = 0; \
|
||||
item; \
|
||||
item = item->next_item, ++index)
|
||||
|
||||
#endif // TOX_WEECHAT_LIST_H
|
||||
|
166
src/twc-message-queue.c
Normal file
166
src/twc-message-queue.c
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-profile.h"
|
||||
#include "twc-utils.h"
|
||||
#include "twc-list.h"
|
||||
|
||||
#include "twc-message-queue.h"
|
||||
|
||||
/**
|
||||
* Get a message queue for a friend, or create one if it does not exist.
|
||||
*/
|
||||
struct t_twc_list *
|
||||
twc_message_queue_get_or_create(struct t_twc_profile *profile,
|
||||
int32_t friend_number)
|
||||
{
|
||||
struct t_twc_list *message_queue = weechat_hashtable_get(profile->message_queues, &friend_number);
|
||||
if (!message_queue)
|
||||
{
|
||||
message_queue = twc_list_new();
|
||||
weechat_hashtable_set(profile->message_queues,
|
||||
&friend_number,
|
||||
message_queue);
|
||||
}
|
||||
|
||||
return message_queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a friend message to the message queue and tries to send it if the
|
||||
* friend is online. Handles splitting of messages. (TODO: actually split messages)
|
||||
*/
|
||||
void
|
||||
twc_message_queue_add_friend_message(struct t_twc_profile *profile,
|
||||
int32_t friend_number,
|
||||
const char *message,
|
||||
enum TWC_MESSAGE_TYPE message_type)
|
||||
{
|
||||
struct t_twc_queued_message *queued_message
|
||||
= malloc(sizeof(struct t_twc_queued_message));
|
||||
|
||||
time_t rawtime = time(NULL);
|
||||
queued_message->time = malloc(sizeof(struct tm));
|
||||
memcpy(queued_message->time, gmtime(&rawtime), sizeof(struct tm));
|
||||
|
||||
queued_message->message = strdup(message);
|
||||
queued_message->message_type = message_type;
|
||||
|
||||
// create a queue if needed and add message
|
||||
struct t_twc_list *message_queue
|
||||
= twc_message_queue_get_or_create(profile, friend_number);
|
||||
twc_list_item_new_data_add(message_queue, queued_message);
|
||||
|
||||
// flush if friend is online
|
||||
if (profile->tox
|
||||
&& tox_get_friend_connection_status(profile->tox, friend_number) == 1)
|
||||
twc_message_queue_flush_friend(profile, friend_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try sending queued messages for a friend.
|
||||
*/
|
||||
void
|
||||
twc_message_queue_flush_friend(struct t_twc_profile *profile,
|
||||
int32_t friend_number)
|
||||
{
|
||||
struct t_twc_list *message_queue
|
||||
= twc_message_queue_get_or_create(profile, friend_number);
|
||||
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(message_queue, index, item)
|
||||
{
|
||||
struct t_twc_queued_message *queued_message = item->queued_message;
|
||||
|
||||
// TODO: store and deal with message IDs
|
||||
uint32_t rc;
|
||||
switch(queued_message->message_type)
|
||||
{
|
||||
case TWC_MESSAGE_TYPE_MESSAGE:
|
||||
rc = tox_send_message(profile->tox,
|
||||
friend_number,
|
||||
(uint8_t *)queued_message->message,
|
||||
strlen(queued_message->message));
|
||||
break;
|
||||
case TWC_MESSAGE_TYPE_ACTION:
|
||||
rc = tox_send_action(profile->tox,
|
||||
friend_number,
|
||||
(uint8_t *)queued_message->message,
|
||||
strlen(queued_message->message));
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
// break if message send failed
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// message was sent, free it
|
||||
twc_message_queue_free_message(queued_message);
|
||||
item->queued_message = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// remove any now-empty items
|
||||
while (message_queue->head && !(message_queue->head->queued_message))
|
||||
twc_list_remove(message_queue->head);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a queued message.
|
||||
*/
|
||||
void
|
||||
twc_message_queue_free_message(struct t_twc_queued_message *message)
|
||||
{
|
||||
free(message->time);
|
||||
free(message->message);
|
||||
free(message);
|
||||
}
|
||||
|
||||
void
|
||||
twc_message_queue_free_map_callback(void *data, struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
struct t_twc_list *message_queue = ((struct t_twc_list *)value);
|
||||
|
||||
struct t_twc_queued_message *message;
|
||||
while ((message = twc_list_pop(message_queue)))
|
||||
twc_message_queue_free_message(message);
|
||||
|
||||
free(message_queue);
|
||||
}
|
||||
|
||||
void
|
||||
twc_message_queue_free_profile(struct t_twc_profile *profile)
|
||||
{
|
||||
weechat_hashtable_map(profile->message_queues,
|
||||
twc_message_queue_free_map_callback, NULL);
|
||||
weechat_hashtable_free(profile->message_queues);
|
||||
}
|
||||
|
56
src/twc-message-queue.h
Normal file
56
src/twc-message-queue.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_MESSAGE_QUEUE_H
|
||||
#define TOX_WEECHAT_MESSAGE_QUEUE_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc-chat.h"
|
||||
|
||||
struct t_twc_profile;
|
||||
struct t_twc_list_item;
|
||||
|
||||
struct t_twc_queued_message
|
||||
{
|
||||
struct tm *time;
|
||||
char *message;
|
||||
enum TWC_MESSAGE_TYPE message_type;
|
||||
};
|
||||
|
||||
void
|
||||
twc_message_queue_add_friend_message(struct t_twc_profile *profile,
|
||||
int32_t friend_number,
|
||||
const char *message,
|
||||
enum TWC_MESSAGE_TYPE message_type);
|
||||
|
||||
void
|
||||
twc_message_queue_flush_friend(struct t_twc_profile *profile,
|
||||
int32_t friend_number);
|
||||
|
||||
void
|
||||
twc_message_queue_free_message(struct t_twc_queued_message *message);
|
||||
|
||||
void
|
||||
twc_message_queue_free_profile(struct t_twc_profile *profile);
|
||||
|
||||
#endif // TOX_WEECHAT_MESSAGE_QUEUE_H
|
||||
|
456
src/twc-profile.c
Normal file
456
src/twc-profile.c
Normal file
@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-bootstrap.h"
|
||||
#include "twc-list.h"
|
||||
#include "twc-config.h"
|
||||
#include "twc-friend-request.h"
|
||||
#include "twc-message-queue.h"
|
||||
#include "twc-chat.h"
|
||||
#include "twc-tox-callbacks.h"
|
||||
#include "twc-utils.h"
|
||||
#include "twc-data.h"
|
||||
|
||||
#include "twc-profile.h"
|
||||
|
||||
struct t_twc_list *twc_profiles = NULL;
|
||||
|
||||
/**
|
||||
* Get a profile's expanded data path, replacing:
|
||||
* - %h with WeeChat home
|
||||
* - %p with profile name
|
||||
*
|
||||
* Returned string must be freed.
|
||||
*/
|
||||
char *
|
||||
twc_profile_expanded_data_path(struct t_twc_profile *profile)
|
||||
{
|
||||
const char *weechat_dir = weechat_info_get ("weechat_dir", NULL);
|
||||
const char *base_path = weechat_config_string(profile->options[TWC_PROFILE_OPTION_SAVEFILE]);
|
||||
char *home_expanded = weechat_string_replace(base_path, "%h", weechat_dir);
|
||||
char *full_path = weechat_string_replace(home_expanded, "%p", profile->name);
|
||||
free(home_expanded);
|
||||
|
||||
return full_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try loading a Tox save file for a profile.
|
||||
*
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*
|
||||
* TODO: support encrypted save files
|
||||
*/
|
||||
int
|
||||
twc_profile_load_data(struct t_twc_profile *profile)
|
||||
{
|
||||
char *full_path = twc_profile_expanded_data_path(profile);
|
||||
FILE *file = fopen(full_path, "r");
|
||||
free(full_path);
|
||||
|
||||
if (file)
|
||||
{
|
||||
// get file size
|
||||
fseek(file, 0, SEEK_END);
|
||||
size_t size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
// allocate a buffer and read file into it
|
||||
uint8_t *data = malloc(sizeof(*data) * size);
|
||||
fread(data, sizeof(uint8_t), size, file);
|
||||
fclose(file);
|
||||
|
||||
// try loading the data
|
||||
int status = tox_load(profile->tox, data, size);
|
||||
free(data);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a profile's Tox data to disk.
|
||||
*
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*
|
||||
* TODO: support encrypted save files
|
||||
*/
|
||||
int
|
||||
twc_save_profile_data_file(struct t_twc_profile *profile)
|
||||
{
|
||||
if (!(profile->tox))
|
||||
return -1;
|
||||
|
||||
char *full_path = twc_profile_expanded_data_path(profile);
|
||||
|
||||
// create containing folder if it doesn't exist
|
||||
char *rightmost_slash = strrchr(full_path, '/');
|
||||
char *dir_path = weechat_strndup(full_path, rightmost_slash - full_path);
|
||||
weechat_mkdir_parents(dir_path, 0755);
|
||||
free(dir_path);
|
||||
|
||||
// save Tox data to a buffer
|
||||
uint32_t size = tox_size(profile->tox);
|
||||
uint8_t *data = malloc(size);
|
||||
tox_save(profile->tox, data);
|
||||
|
||||
// save buffer to a file
|
||||
FILE *file = fopen(full_path, "w");
|
||||
if (file)
|
||||
{
|
||||
size_t saved_size = fwrite(data, sizeof(data[0]), size, file);
|
||||
fclose(file);
|
||||
|
||||
return saved_size == size;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback when a profile's main buffer is closed. Unloads the profile.
|
||||
*/
|
||||
int
|
||||
twc_profile_buffer_close_callback(void *data,
|
||||
struct t_gui_buffer *buffer)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
|
||||
profile->buffer = NULL;
|
||||
twc_profile_unload(profile);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Tox profiles list.
|
||||
*/
|
||||
void
|
||||
twc_profile_init()
|
||||
{
|
||||
twc_profiles = twc_list_new();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new profile object and add it to the list of profiles.
|
||||
*/
|
||||
struct t_twc_profile *
|
||||
twc_profile_new(const char *name)
|
||||
{
|
||||
struct t_twc_profile *profile = malloc(sizeof(struct t_twc_profile));
|
||||
profile->name = strdup(name);
|
||||
|
||||
// add to profile list
|
||||
twc_list_item_new_data_add(twc_profiles, profile);
|
||||
|
||||
// set up internal vars
|
||||
profile->tox = NULL;
|
||||
profile->buffer = NULL;
|
||||
profile->tox_do_timer = NULL;
|
||||
profile->tox_online = false;
|
||||
|
||||
profile->chats = twc_list_new();
|
||||
profile->friend_requests = twc_list_new();
|
||||
profile->message_queues = weechat_hashtable_new(10,
|
||||
WEECHAT_HASHTABLE_INTEGER,
|
||||
WEECHAT_HASHTABLE_POINTER,
|
||||
NULL, NULL);
|
||||
|
||||
// set up config
|
||||
twc_config_init_profile(profile);
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a profile's Tox object, creating a new one if it can't be loaded from
|
||||
* disk, and bootstraps the Tox DHT.
|
||||
*/
|
||||
void
|
||||
twc_profile_load(struct t_twc_profile *profile)
|
||||
{
|
||||
if (profile->tox)
|
||||
return;
|
||||
|
||||
if (!(profile->buffer))
|
||||
{
|
||||
// create main buffer
|
||||
profile->buffer = weechat_buffer_new(profile->name,
|
||||
NULL, NULL,
|
||||
twc_profile_buffer_close_callback, profile);
|
||||
if (!(profile->buffer))
|
||||
return;
|
||||
}
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s: profile %s connecting",
|
||||
weechat_prefix("network"), weechat_plugin->name,
|
||||
profile->name);
|
||||
|
||||
// TODO: this does nothing
|
||||
if (profile->friend_requests->count > 0)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sYou have %d pending friend requests.",
|
||||
weechat_prefix("network"),
|
||||
profile->friend_requests->count);
|
||||
}
|
||||
|
||||
// create Tox
|
||||
profile->tox = tox_new(NULL);
|
||||
if (!(profile->tox))
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"Could not create Tox instance!",
|
||||
weechat_prefix("error"), weechat_plugin->name);
|
||||
return;
|
||||
}
|
||||
|
||||
// try loading Tox saved data
|
||||
if (twc_profile_load_data(profile) == -1)
|
||||
{
|
||||
// we failed to load - set some defaults
|
||||
char *name;
|
||||
struct passwd *user_pwd;
|
||||
if ((user_pwd = getpwuid(geteuid())))
|
||||
name = user_pwd->pw_name;
|
||||
else
|
||||
name = "Tox-WeeChat User";
|
||||
|
||||
tox_set_name(profile->tox,
|
||||
(uint8_t *)name, strlen(name));
|
||||
}
|
||||
|
||||
// bootstrap DHT
|
||||
// TODO: add count to config
|
||||
int bootstrap_node_count = 5;
|
||||
for (int i = 0; i < bootstrap_node_count; ++i)
|
||||
twc_bootstrap_random_node(profile->tox);
|
||||
|
||||
// start Tox_do loop
|
||||
twc_do_timer_cb(profile, 0);
|
||||
|
||||
// register Tox callbacks
|
||||
tox_callback_friend_message(profile->tox, twc_friend_message_callback, profile);
|
||||
tox_callback_friend_action(profile->tox, twc_friend_action_callback, profile);
|
||||
tox_callback_connection_status(profile->tox, twc_connection_status_callback, profile);
|
||||
tox_callback_name_change(profile->tox, twc_name_change_callback, profile);
|
||||
tox_callback_user_status(profile->tox, twc_user_status_callback, profile);
|
||||
tox_callback_status_message(profile->tox, twc_status_message_callback, profile);
|
||||
tox_callback_friend_request(profile->tox, twc_friend_request_callback, profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload a Tox profile. Disconnects from the network, saves data to disk.
|
||||
*/
|
||||
void
|
||||
twc_profile_unload(struct t_twc_profile *profile)
|
||||
{
|
||||
// check that we're not already disconnected
|
||||
if (!(profile->tox))
|
||||
return;
|
||||
|
||||
// save and kill tox
|
||||
int result = twc_save_profile_data_file(profile);
|
||||
tox_kill(profile->tox);
|
||||
profile->tox = NULL;
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
char *path = twc_profile_expanded_data_path(profile);
|
||||
weechat_printf(NULL,
|
||||
"%s%s: Could not save Tox data for profile %s to file: %s",
|
||||
weechat_prefix("error"), weechat_plugin->name,
|
||||
profile->name,
|
||||
path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
// stop Tox timer
|
||||
weechat_unhook(profile->tox_do_timer);
|
||||
|
||||
// have to refresh and hide bar items even if we were already offline
|
||||
// TODO
|
||||
twc_profile_refresh_online_status(profile);
|
||||
twc_profile_set_online_status(profile, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load profiles that should autoload.
|
||||
*/
|
||||
void
|
||||
twc_profile_autoload()
|
||||
{
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(twc_profiles, index, item)
|
||||
{
|
||||
if (weechat_config_boolean(item->profile->options[TWC_PROFILE_OPTION_AUTOLOAD]))
|
||||
twc_profile_load(item->profile);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
twc_profile_refresh_online_status(struct t_twc_profile *profile)
|
||||
{
|
||||
weechat_bar_item_update("buffer_plugin");
|
||||
weechat_bar_item_update("input_prompt");
|
||||
weechat_bar_item_update("away");
|
||||
}
|
||||
|
||||
void
|
||||
twc_profile_set_online_status(struct t_twc_profile *profile,
|
||||
bool status)
|
||||
{
|
||||
if (profile->tox_online ^ status)
|
||||
{
|
||||
profile->tox_online = status;
|
||||
twc_profile_refresh_online_status(profile);
|
||||
|
||||
if (profile->tox_online)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s: profile %s connected",
|
||||
weechat_prefix("network"),
|
||||
weechat_plugin->name,
|
||||
profile->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s: profile %s disconnected",
|
||||
weechat_prefix("network"),
|
||||
weechat_plugin->name,
|
||||
profile->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the profile with a certain name. Case insensitive.
|
||||
*/
|
||||
struct t_twc_profile *
|
||||
twc_profile_search_name(const char *name)
|
||||
{
|
||||
size_t index;
|
||||
struct t_twc_list_item *item;
|
||||
twc_list_foreach(twc_profiles, index, item)
|
||||
{
|
||||
if (weechat_strcasecmp(item->profile->name, name) == 0)
|
||||
return item->profile;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the profile associated with a buffer, if any.
|
||||
*/
|
||||
struct t_twc_profile *
|
||||
twc_profile_search_buffer(struct t_gui_buffer *buffer)
|
||||
{
|
||||
size_t profile_index;
|
||||
struct t_twc_list_item *profile_item;
|
||||
twc_list_foreach(twc_profiles, profile_index, profile_item)
|
||||
{
|
||||
if (profile_item->profile->buffer == buffer)
|
||||
return profile_item->profile;
|
||||
|
||||
size_t chat_index;
|
||||
struct t_twc_list_item *chat_item;
|
||||
twc_list_foreach(profile_item->profile->chats, chat_index, chat_item)
|
||||
{
|
||||
if (chat_item->chat->buffer == buffer)
|
||||
return profile_item->profile;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a profile. Unloads, frees and deletes everything. If delete_data is
|
||||
* true, Tox data on disk is also deleted.
|
||||
*/
|
||||
void
|
||||
twc_profile_delete(struct t_twc_profile *profile,
|
||||
bool delete_data)
|
||||
{
|
||||
char *data_path = twc_profile_expanded_data_path(profile);
|
||||
|
||||
twc_profile_free(profile);
|
||||
|
||||
if (delete_data)
|
||||
unlink(data_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees a profile. Unloads and frees all variables.
|
||||
*/
|
||||
void
|
||||
twc_profile_free(struct t_twc_profile *profile)
|
||||
{
|
||||
// unload if needed
|
||||
twc_profile_unload(profile);
|
||||
|
||||
// close buffer
|
||||
if (profile->buffer)
|
||||
{
|
||||
weechat_buffer_set_pointer(profile->buffer, "close_callback", NULL);
|
||||
weechat_buffer_close(profile->buffer);
|
||||
}
|
||||
|
||||
// free things
|
||||
twc_friend_request_free_profile(profile);
|
||||
twc_chat_free_profile(profile);
|
||||
twc_message_queue_free_profile(profile);
|
||||
free(profile->name);
|
||||
free(profile);
|
||||
|
||||
// remove from list
|
||||
twc_list_remove_with_data(twc_profiles, profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all profiles.
|
||||
*/
|
||||
void
|
||||
twc_profile_free_all()
|
||||
{
|
||||
struct t_twc_profile *profile;
|
||||
while ((profile = twc_list_pop(twc_profiles)))
|
||||
twc_profile_free(profile);
|
||||
|
||||
free(twc_profiles);
|
||||
}
|
||||
|
94
src/twc-profile.h
Normal file
94
src/twc-profile.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_PROFILE_H
|
||||
#define TOX_WEECHAT_PROFILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
struct t_hashtable;
|
||||
|
||||
enum t_twc_profile_option
|
||||
{
|
||||
TWC_PROFILE_OPTION_SAVEFILE = 0,
|
||||
TWC_PROFILE_OPTION_AUTOLOAD,
|
||||
TWC_PROFILE_OPTION_MAX_FRIEND_REQUESTS,
|
||||
|
||||
TWC_PROFILE_NUM_OPTIONS,
|
||||
};
|
||||
|
||||
struct t_twc_profile
|
||||
{
|
||||
char *name;
|
||||
struct t_config_option *options[TWC_PROFILE_NUM_OPTIONS];
|
||||
|
||||
struct Tox *tox;
|
||||
int tox_online;
|
||||
|
||||
struct t_gui_buffer *buffer;
|
||||
struct t_hook *tox_do_timer;
|
||||
|
||||
struct t_twc_list *friend_requests;
|
||||
struct t_twc_list *chats;
|
||||
struct t_hashtable *message_queues;
|
||||
};
|
||||
|
||||
extern struct t_twc_list *twc_profiles;
|
||||
|
||||
void
|
||||
twc_profile_init();
|
||||
|
||||
struct t_twc_profile *
|
||||
twc_profile_new(const char *name);
|
||||
|
||||
void
|
||||
twc_profile_load(struct t_twc_profile *profile);
|
||||
|
||||
void
|
||||
twc_profile_unload(struct t_twc_profile *profile);
|
||||
|
||||
void
|
||||
twc_profile_autoload();
|
||||
|
||||
void
|
||||
twc_profile_refresh_online_status(struct t_twc_profile *profile);
|
||||
|
||||
void
|
||||
twc_profile_set_online_status(struct t_twc_profile *profile, bool online);
|
||||
|
||||
struct t_twc_profile *
|
||||
twc_profile_search_name(const char *name);
|
||||
|
||||
struct t_twc_profile *
|
||||
twc_profile_search_buffer(struct t_gui_buffer *buffer);
|
||||
|
||||
void
|
||||
twc_profile_delete(struct t_twc_profile *profile, bool delete_data);
|
||||
|
||||
void
|
||||
twc_profile_free(struct t_twc_profile *profile);
|
||||
|
||||
void
|
||||
twc_profile_free_all();
|
||||
|
||||
#endif // TOX_WEECHAT_PROFILE_H
|
||||
|
231
src/twc-tox-callbacks.c
Normal file
231
src/twc-tox-callbacks.c
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "twc.h"
|
||||
#include "twc-profile.h"
|
||||
#include "twc-chat.h"
|
||||
#include "twc-friend-request.h"
|
||||
#include "twc-message-queue.h"
|
||||
#include "twc-utils.h"
|
||||
|
||||
#include "twc-tox-callbacks.h"
|
||||
|
||||
int
|
||||
twc_do_timer_cb(void *data,
|
||||
int remaining_calls)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
|
||||
tox_do(profile->tox);
|
||||
struct t_hook *hook = weechat_hook_timer(tox_do_interval(profile->tox), 0, 1,
|
||||
twc_do_timer_cb, profile);
|
||||
profile->tox_do_timer = hook;
|
||||
|
||||
// check connection status
|
||||
int connected = tox_isconnected(profile->tox);
|
||||
twc_profile_set_online_status(profile, connected);
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
void
|
||||
twc_friend_message_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
struct t_twc_chat *chat = twc_chat_search_friend(profile,
|
||||
friend_number,
|
||||
true);
|
||||
|
||||
char *name = twc_get_name_nt(profile->tox, friend_number);
|
||||
char *message_nt = twc_null_terminate(message, length);
|
||||
|
||||
twc_chat_print_message(chat, "", name,
|
||||
message_nt, TWC_MESSAGE_TYPE_MESSAGE);
|
||||
|
||||
free(name);
|
||||
free(message_nt);
|
||||
}
|
||||
|
||||
void
|
||||
twc_friend_action_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
|
||||
struct t_twc_chat *chat = twc_chat_search_friend(profile,
|
||||
friend_number,
|
||||
true);
|
||||
|
||||
char *name = twc_get_name_nt(profile->tox, friend_number);
|
||||
char *message_nt = twc_null_terminate(message, length);
|
||||
|
||||
twc_chat_print_message(chat, "", name,
|
||||
message_nt, TWC_MESSAGE_TYPE_ACTION);
|
||||
|
||||
free(name);
|
||||
free(message_nt);
|
||||
}
|
||||
|
||||
void
|
||||
twc_connection_status_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
uint8_t status,
|
||||
void *data)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
char *name = twc_get_name_nt(profile->tox, friend_number);
|
||||
|
||||
// TODO: print in friend's buffer if it exists
|
||||
if (status == 0)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s just went offline.",
|
||||
weechat_prefix("network"),
|
||||
name);
|
||||
}
|
||||
else if (status == 1)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s just came online.",
|
||||
weechat_prefix("network"),
|
||||
name);
|
||||
twc_message_queue_flush_friend(profile, friend_number);
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
|
||||
void
|
||||
twc_name_change_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *name,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
struct t_twc_chat *chat = twc_chat_search_friend(profile,
|
||||
friend_number,
|
||||
false);
|
||||
|
||||
char *old_name = twc_get_name_nt(profile->tox, friend_number);
|
||||
char *new_name = twc_null_terminate(name, length);
|
||||
|
||||
if (strcmp(old_name, new_name) != 0)
|
||||
{
|
||||
if (chat)
|
||||
{
|
||||
twc_chat_queue_refresh(chat);
|
||||
|
||||
weechat_printf(chat->buffer,
|
||||
"%s%s is now known as %s",
|
||||
weechat_prefix("network"),
|
||||
old_name, new_name);
|
||||
}
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%s%s is now known as %s",
|
||||
weechat_prefix("network"),
|
||||
old_name, new_name);
|
||||
}
|
||||
|
||||
free(old_name);
|
||||
free(new_name);
|
||||
}
|
||||
|
||||
void
|
||||
twc_user_status_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
uint8_t status,
|
||||
void *data)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
struct t_twc_chat *chat = twc_chat_search_friend(profile,
|
||||
friend_number,
|
||||
false);
|
||||
if (chat)
|
||||
twc_chat_queue_refresh(chat);
|
||||
}
|
||||
|
||||
void
|
||||
twc_status_message_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
struct t_twc_chat *chat = twc_chat_search_friend(profile,
|
||||
friend_number,
|
||||
false);
|
||||
if (chat)
|
||||
twc_chat_queue_refresh(chat);
|
||||
}
|
||||
|
||||
void
|
||||
twc_friend_request_callback(Tox *tox,
|
||||
const uint8_t *public_key,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data)
|
||||
{
|
||||
struct t_twc_profile *profile = data;
|
||||
|
||||
char *message_nt = twc_null_terminate(message, length);
|
||||
int rc = twc_friend_request_add(profile, public_key, message_nt);
|
||||
|
||||
if (rc == -1)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sReceived a friend request, but your friend request list is full!",
|
||||
weechat_prefix("warning"));
|
||||
}
|
||||
else
|
||||
{
|
||||
char hex_address[TOX_CLIENT_ID_SIZE * 2 + 1];
|
||||
twc_bin2hex(public_key, TOX_CLIENT_ID_SIZE, hex_address);
|
||||
|
||||
weechat_printf(profile->buffer,
|
||||
"%sReceived a friend request with message \"%s\" from %s",
|
||||
weechat_prefix("network"),
|
||||
message_nt,
|
||||
hex_address);
|
||||
|
||||
if (rc == -2)
|
||||
{
|
||||
weechat_printf(profile->buffer,
|
||||
"%sFailed to save friend request, try manually "
|
||||
"accepting with /friend add",
|
||||
weechat_prefix("error"));
|
||||
}
|
||||
}
|
||||
|
||||
free(message_nt);
|
||||
}
|
||||
|
79
src/twc-tox-callbacks.h
Normal file
79
src/twc-tox-callbacks.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Håvard Pettersson <haavard.pettersson@gmail.com>
|
||||
*
|
||||
* This file is part of Tox-WeeChat.
|
||||
*
|
||||
* Tox-WeeChat is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox-WeeChat is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox-WeeChat. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TOX_WEECHAT_TOX_CALLBACKS_H
|
||||
#define TOX_WEECHAT_TOX_CALLBACKS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
int
|
||||
twc_do_timer_cb(void *data,
|
||||
int remaining_calls);
|
||||
|
||||
void
|
||||
twc_friend_message_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
void
|
||||
twc_friend_action_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
void
|
||||
twc_connection_status_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
uint8_t status,
|
||||
void *data);
|
||||
|
||||
void
|
||||
twc_name_change_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *name,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
void
|
||||
twc_user_status_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
uint8_t status,
|
||||
void *data);
|
||||
|
||||
void
|
||||
twc_status_message_callback(Tox *tox,
|
||||
int32_t friend_number,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
void
|
||||
twc_friend_request_callback(Tox *tox,
|
||||
const uint8_t *public_key,
|
||||
const uint8_t *message,
|
||||
uint16_t length,
|
||||
void *data);
|
||||
|
||||
#endif // TOX_WEECHAT_TOX_CALLBACKS_H
|
||||
|
@ -25,28 +25,37 @@
|
||||
#include <weechat/weechat-plugin.h>
|
||||
#include <tox/tox.h>
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "twc.h"
|
||||
|
||||
#include "tox-weechat-utils.h"
|
||||
#include "twc-utils.h"
|
||||
|
||||
/**
|
||||
* Convert a hex string to it's binary equivalent of max size bytes.
|
||||
*/
|
||||
void
|
||||
tox_weechat_hex2bin(const char *hex, size_t length, char *out)
|
||||
twc_hex2bin(const char *hex, size_t size, char *out)
|
||||
{
|
||||
const char *position = hex;
|
||||
|
||||
for (size_t i = 0; i < length / 2; ++i)
|
||||
size_t i;
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
sscanf(position, "%2hhx", &out[i]);
|
||||
position += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert size bytes to a hex string. out must be at lesat size * 2 + 1
|
||||
* bytes.
|
||||
*/
|
||||
void
|
||||
tox_weechat_bin2hex(const uint8_t *bin, size_t size, char *out)
|
||||
twc_bin2hex(const uint8_t *bin, size_t size, char *out)
|
||||
{
|
||||
char *position = out;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
size_t i;
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
sprintf(position, "%02X", bin[i]);
|
||||
position += 2;
|
||||
@ -54,8 +63,11 @@ tox_weechat_bin2hex(const uint8_t *bin, size_t size, char *out)
|
||||
*position = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a null-terminated copy of str. Must be freed.
|
||||
*/
|
||||
char *
|
||||
tox_weechat_null_terminate(const uint8_t *str, size_t length)
|
||||
twc_null_terminate(const uint8_t *str, size_t length)
|
||||
{
|
||||
char *str_null = malloc(length + 1);
|
||||
memcpy(str_null, str, length);
|
||||
@ -64,44 +76,66 @@ tox_weechat_null_terminate(const uint8_t *str, size_t length)
|
||||
return str_null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the null-terminated name of a Tox friend. Must be freed.
|
||||
*/
|
||||
char *
|
||||
tox_weechat_get_name_nt(Tox *tox, int32_t friend_number)
|
||||
twc_get_name_nt(Tox *tox, int32_t friend_number)
|
||||
{
|
||||
size_t length = tox_get_name_size(tox, friend_number);
|
||||
uint8_t name[length];
|
||||
|
||||
// if no name, return client ID instead
|
||||
if (!length)
|
||||
{
|
||||
uint8_t client_id[TOX_CLIENT_ID_SIZE];
|
||||
tox_get_client_id(tox, friend_number, client_id);
|
||||
|
||||
char *hex = malloc(TOX_CLIENT_ID_SIZE * 2 + 1);
|
||||
tox_weechat_bin2hex(client_id, TOX_CLIENT_ID_SIZE, hex);
|
||||
|
||||
return hex;
|
||||
}
|
||||
return twc_get_friend_id_short(tox, friend_number);
|
||||
|
||||
tox_get_name(tox, friend_number, name);
|
||||
return tox_weechat_null_terminate(name, length);
|
||||
return twc_null_terminate(name, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the null-terminated status message of a Tox friend. Must be freed.
|
||||
*/
|
||||
char *
|
||||
tox_weechat_get_status_message_nt(Tox *tox, int32_t friend_number)
|
||||
twc_get_status_message_nt(Tox *tox, int32_t friend_number)
|
||||
{
|
||||
size_t length = tox_get_status_message_size(tox, friend_number);
|
||||
uint8_t message[length];
|
||||
tox_get_status_message(tox, friend_number, message, length);
|
||||
|
||||
return tox_weechat_null_terminate(message, length);
|
||||
return twc_null_terminate(message, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the users own name, null-terminated. Must be freed.
|
||||
*/
|
||||
char *
|
||||
tox_weechat_get_self_name_nt(Tox *tox)
|
||||
twc_get_self_name_nt(Tox *tox)
|
||||
{
|
||||
size_t length = tox_get_self_name_size(tox);
|
||||
uint8_t name[length];
|
||||
tox_get_self_name(tox, name);
|
||||
|
||||
return tox_weechat_null_terminate(name, length);
|
||||
return twc_null_terminate(name, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a friend's Tox ID in short form. Return value must be freed.
|
||||
*/
|
||||
char *
|
||||
twc_get_friend_id_short(Tox *tox, int32_t friend_number)
|
||||
{
|
||||
uint8_t client_id[TOX_CLIENT_ID_SIZE];
|
||||
tox_get_client_id(tox, friend_number, client_id);
|
||||
|
||||
// TODO: config
|
||||
size_t short_id_length = 8;
|
||||
|
||||
char *hex_address = malloc(short_id_length + 1);
|
||||
twc_bin2hex(client_id,
|
||||
short_id_length / 2,
|
||||
hex_address);
|
||||
|
||||
return hex_address;
|
||||
}
|
||||
|
@ -26,21 +26,25 @@
|
||||
#include <tox/tox.h>
|
||||
|
||||
void
|
||||
tox_weechat_hex2bin(const char *hex, size_t length, char *out);
|
||||
twc_hex2bin(const char *hex, size_t size, char *out);
|
||||
|
||||
void
|
||||
tox_weechat_bin2hex(const uint8_t *bin, size_t size, char *out);
|
||||
twc_bin2hex(const uint8_t *bin, size_t size, char *out);
|
||||
|
||||
char *
|
||||
tox_weechat_null_terminate(const uint8_t *str, size_t length);
|
||||
twc_null_terminate(const uint8_t *str, size_t length);
|
||||
|
||||
char *
|
||||
tox_weechat_get_name_nt(Tox *tox, int32_t friend_number);
|
||||
twc_get_name_nt(Tox *tox, int32_t friend_number);
|
||||
|
||||
char *
|
||||
tox_weechat_get_status_message_nt(Tox *tox, int32_t friend_number);
|
||||
twc_get_status_message_nt(Tox *tox, int32_t friend_number);
|
||||
|
||||
char *
|
||||
tox_weechat_get_self_name_nt(Tox *tox);
|
||||
twc_get_self_name_nt(Tox *tox);
|
||||
|
||||
char *
|
||||
twc_get_friend_id_short(Tox *tox, int32_t friend_number);
|
||||
|
||||
#endif // TOX_WEECHAT_UTILS_H
|
||||
|
@ -21,15 +21,15 @@
|
||||
|
||||
#include <weechat/weechat-plugin.h>
|
||||
|
||||
#include "tox-weechat-identities.h"
|
||||
#include "tox-weechat-commands.h"
|
||||
#include "tox-weechat-gui.h"
|
||||
#include "tox-weechat-friend-requests.h"
|
||||
#include "tox-weechat-config.h"
|
||||
#include "tox-weechat-data.h"
|
||||
#include "tox-weechat-completion.h"
|
||||
#include "twc-profile.h"
|
||||
#include "twc-commands.h"
|
||||
#include "twc-gui.h"
|
||||
#include "twc-friend-request.h"
|
||||
#include "twc-config.h"
|
||||
#include "twc-data.h"
|
||||
#include "twc-completion.h"
|
||||
|
||||
#include "tox-weechat.h"
|
||||
#include "twc.h"
|
||||
|
||||
WEECHAT_PLUGIN_NAME("tox");
|
||||
WEECHAT_PLUGIN_DESCRIPTION("Tox protocol");
|
||||
@ -38,22 +38,22 @@ WEECHAT_PLUGIN_VERSION("0.1");
|
||||
WEECHAT_PLUGIN_LICENSE("GPL3");
|
||||
|
||||
struct t_weechat_plugin *weechat_plugin = NULL;
|
||||
struct t_gui_buffer *tox_main_buffer = NULL;
|
||||
int tox_weechat_online_status = 0;
|
||||
|
||||
int
|
||||
weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
{
|
||||
weechat_plugin = plugin;
|
||||
|
||||
tox_weechat_config_init();
|
||||
tox_weechat_config_read();
|
||||
tox_weechat_data_load();
|
||||
tox_weechat_commands_init();
|
||||
tox_weechat_gui_init();
|
||||
tox_weechat_completion_init();
|
||||
twc_profile_init();
|
||||
twc_commands_init();
|
||||
twc_gui_init();
|
||||
twc_completion_init();
|
||||
|
||||
tox_weechat_identity_autoconnect();
|
||||
twc_config_init();
|
||||
twc_config_read();
|
||||
|
||||
// TODO: respect weechat flag for no autoconnect
|
||||
twc_profile_autoload();
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
@ -61,10 +61,10 @@ weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
int
|
||||
weechat_plugin_end(struct t_weechat_plugin *plugin)
|
||||
{
|
||||
tox_weechat_config_write();
|
||||
tox_weechat_identity_free_all();
|
||||
tox_weechat_data_save();
|
||||
tox_weechat_data_free();
|
||||
twc_config_write();
|
||||
|
||||
twc_profile_free_all();
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
@ -20,8 +20,7 @@
|
||||
#ifndef TOX_WEECHAT_H
|
||||
#define TOX_WEECHAT_H
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
extern struct t_weechat_plugin *weechat_plugin;
|
||||
|
||||
#endif // TOX_WEECHAT_H
|
||||
|
Loading…
Reference in New Issue
Block a user