mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-23 01:03:02 +01:00
Port to new group API
This commit is contained in:
commit
a846c38695
57
.travis.yml
57
.travis.yml
@ -1,52 +1,23 @@
|
|||||||
language: c
|
env:
|
||||||
compiler:
|
secure: m+RsGCgemJNMKbinD97PtjC1pUuFzDBrAol3tI6Z3xP1FE2qF0/efbcC5OyNwUWwcaqGRb83d0vWt4hzhxMwrwJC8O6EFLFHgJs0WpslP+++KRN30PUOqRFFqH404InF4pFNULlnwJYFZ8bGft4ThxppbEOeSYcXN4WSgb66RjM=
|
||||||
- gcc
|
|
||||||
- clang
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
# Installing yasm (needed for compiling vpx) and openal
|
- sudo apt-get install wget
|
||||||
- sudo apt-get -yq install yasm libopenal-dev libconfig-dev libalut-dev libnotify-dev clang llvm-dev
|
|
||||||
# Installing libsodium, needed for toxcore
|
|
||||||
- git clone https://github.com/jedisct1/libsodium.git libsodium
|
|
||||||
- cd libsodium
|
|
||||||
- git checkout tags/1.0.3 > /dev/null
|
|
||||||
- ./autogen.sh > /dev/null
|
|
||||||
- ./configure > /dev/null
|
|
||||||
- make check -j2 || make check || exit 1 > /dev/null
|
|
||||||
- sudo make install > /dev/null
|
|
||||||
- cd ..
|
|
||||||
# Installing libopus, needed for audio encoding/decoding
|
|
||||||
- wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz
|
|
||||||
- tar xzf opus-1.1.tar.gz > /dev/null
|
|
||||||
- cd opus-1.1
|
|
||||||
- ./configure > /dev/null
|
|
||||||
- make -j2 || make || exit 1 > /dev/null
|
|
||||||
- sudo make install > /dev/null
|
|
||||||
- cd ..
|
|
||||||
# Installing vpx
|
|
||||||
- git clone https://chromium.googlesource.com/webm/libvpx libvpx
|
|
||||||
- cd libvpx
|
|
||||||
- ./configure --enable-shared > /dev/null
|
|
||||||
- make -j2 || make || exit 1 > /dev/null
|
|
||||||
- sudo make install > /dev/null
|
|
||||||
- cd ..
|
|
||||||
# Creating libraries links and updating cache
|
|
||||||
- sudo ldconfig > /dev/null
|
|
||||||
# Installing toxcore
|
|
||||||
- git clone https://github.com/irungentoo/toxcore.git toxcore
|
|
||||||
- cd toxcore
|
|
||||||
- autoreconf -i
|
|
||||||
- ./configure --disable-tests --disable-ntox --disable-daemon --enable-av
|
|
||||||
- make -j2 || make || exit 1
|
|
||||||
- sudo make install
|
|
||||||
- cd ..
|
|
||||||
script:
|
script:
|
||||||
- make -j2 || make || exit 1
|
- wget -O temp https://jenkins.libtoxcore.so/job/toxic_linux_beta/build?token=$TOKEN && cat temp
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
|
||||||
irc:
|
irc:
|
||||||
channels:
|
channels:
|
||||||
- "chat.freenode.net#tox-dev"
|
- "chat.freenode.net#tox-groupchats"
|
||||||
|
on_success: always
|
||||||
|
on_failure: always
|
||||||
|
|
||||||
|
irc:
|
||||||
|
channels:
|
||||||
|
- "chat.freenode.net#tox-groupchats"
|
||||||
on_success: always
|
on_success: always
|
||||||
on_failure: always
|
on_failure: always
|
||||||
|
@ -138,6 +138,11 @@ Indicator for alert messages\&.
|
|||||||
Indicator for normal messages\&.
|
Indicator for normal messages\&.
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
|
\fBline_special\fR
|
||||||
|
.RS 4
|
||||||
|
Indicator for special messages\&.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
\fBmplex_away\fR
|
\fBmplex_away\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Set user status when attaching and detaching from GNU screen or tmux\&. true or false
|
Set user status when attaching and detaching from GNU screen or tmux\&. true or false
|
||||||
|
@ -88,6 +88,9 @@ OPTIONS
|
|||||||
*line_normal*;;
|
*line_normal*;;
|
||||||
Indicator for normal messages.
|
Indicator for normal messages.
|
||||||
|
|
||||||
|
*line_special*;;
|
||||||
|
Indicator for special messages.
|
||||||
|
|
||||||
*mplex_away*;;
|
*mplex_away*;;
|
||||||
Set user status when attaching and detaching from GNU screen or tmux.
|
Set user status when attaching and detaching from GNU screen or tmux.
|
||||||
true or false
|
true or false
|
||||||
|
@ -1,20 +1 @@
|
|||||||
192.254.75.102 33445 951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F
|
192.254.75.104 33445 6058FF1DA1E013AD4F829CBE8E5DDFD30A4DE55901B0997832E3E8A64E19026C
|
||||||
144.76.60.215 33445 04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F
|
|
||||||
23.226.230.47 33445 A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074
|
|
||||||
178.62.125.224 33445 10B20C49ACBD968D7C80F2E8438F92EA51F189F4E70CFBBB2C2C8C799E97F03E
|
|
||||||
178.21.112.187 33445 4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057
|
|
||||||
195.154.119.113 33445 E398A69646B8CEACA9F0B84F553726C1C49270558C57DF5F3C368F05A7D71354
|
|
||||||
192.210.149.121 33445 F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67
|
|
||||||
104.219.184.206 443 8CD087E31C67568103E8C2A28653337E90E6B8EDA0D765D57C6B5172B4F1F04C
|
|
||||||
76.191.23.96 33445 93574A3FAB7D612FEA29FD8D67D3DD10DFD07A075A5D62E8AF3DD9F5D0932E11
|
|
||||||
46.38.239.179 33445 F5A1A38EFB6BD3C2C8AF8B10D85F0F89E931704D349F1D0720C3C4059AF2440A
|
|
||||||
178.62.250.138 33445 788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B
|
|
||||||
78.225.128.39 33445 7A2306BFBA665E5480AE59B31E116BE9C04DCEFE04D9FE25082316FA34B4DA0C
|
|
||||||
130.133.110.14 33445 461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F
|
|
||||||
104.167.101.29 33445 5918AC3C06955962A75AD7DF4F80A5D7C34F7DB9E1498D2E0495DE35B3FE8A57
|
|
||||||
195.154.109.148 33445 391C96CB67AE893D4782B8E4495EB9D89CF1031F48460C06075AA8CE76D50A21
|
|
||||||
192.3.173.88 33445 3E1FFDEB667BFF549F619EC6737834762124F50A89C8D0DBF1DDF64A2DD6CD1B
|
|
||||||
205.185.116.116 33445 A179B09749AC826FF01F37A9613F6B57118AE014D4196A0E1105A98F93A54702
|
|
||||||
198.98.51.198 33445 1D5A5F2F5D6233058BF0259B09622FB40B482E4FA0931EB8FD3AB8E7BF7DAF6F
|
|
||||||
80.232.246.79 33445 0B8DCEAA7BDDC44BB11173F987CAE3566A2D7057D8DD3CC642BD472B9391002A
|
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ ui = {
|
|||||||
// Indicator for normal messages.
|
// Indicator for normal messages.
|
||||||
line_normal="---";
|
line_normal="---";
|
||||||
|
|
||||||
|
// Indicator for special messages (currently only used for private group messages)
|
||||||
|
line_special=">>>";
|
||||||
|
|
||||||
// true to change status based on screen/tmux attach/detach, false to disable
|
// true to change status based on screen/tmux attach/detach, false to disable
|
||||||
mplex_away=true;
|
mplex_away=true;
|
||||||
|
|
||||||
@ -57,7 +60,7 @@ audio = {
|
|||||||
|
|
||||||
// preferred audio output device; numbers correspond to /lsdev out
|
// preferred audio output device; numbers correspond to /lsdev out
|
||||||
output_device=0;
|
output_device=0;
|
||||||
|
|
||||||
// default VAD treshold; float (recommended values are around 40)
|
// default VAD treshold; float (recommended values are around 40)
|
||||||
VAD_treshold=40.0;
|
VAD_treshold=40.0;
|
||||||
};
|
};
|
||||||
|
28
src/chat.c
28
src/chat.c
@ -63,9 +63,9 @@ static void kill_infobox(ToxWindow *self);
|
|||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
#define AC_NUM_CHAT_COMMANDS 27
|
#define AC_NUM_CHAT_COMMANDS 28
|
||||||
#else
|
#else
|
||||||
#define AC_NUM_CHAT_COMMANDS 20
|
#define AC_NUM_CHAT_COMMANDS 21
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
/* Array of chat command names used for tab completion. */
|
/* Array of chat command names used for tab completion. */
|
||||||
@ -78,6 +78,7 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
|
|||||||
{ "/close" },
|
{ "/close" },
|
||||||
{ "/connect" },
|
{ "/connect" },
|
||||||
{ "/exit" },
|
{ "/exit" },
|
||||||
|
{ "/gaccept" },
|
||||||
{ "/group" },
|
{ "/group" },
|
||||||
{ "/help" },
|
{ "/help" },
|
||||||
{ "/invite" },
|
{ "/invite" },
|
||||||
@ -509,25 +510,18 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
|
|||||||
"Incoming file: %s", filename );
|
"Incoming file: %s", filename );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, uint8_t type, const char *group_pub_key,
|
static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, const char *invite_data,
|
||||||
uint16_t length)
|
size_t length)
|
||||||
{
|
{
|
||||||
if (self->num != friendnumber)
|
if (self->num != friendnumber)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Friends.list[friendnumber].group_invite.key != NULL)
|
if (Friends.list[friendnumber].group_invite.data)
|
||||||
free(Friends.list[friendnumber].group_invite.key);
|
free(Friends.list[friendnumber].group_invite.data);
|
||||||
|
|
||||||
char *k = malloc(length);
|
Friends.list[friendnumber].group_invite.data = malloc(length * sizeof(uint8_t));
|
||||||
|
memcpy(Friends.list[friendnumber].group_invite.data, invite_data, length);
|
||||||
if (k == NULL)
|
|
||||||
exit_toxic_err("Failed in chat_onGroupInvite", FATALERR_MEMORY);
|
|
||||||
|
|
||||||
memcpy(k, group_pub_key, length);
|
|
||||||
Friends.list[friendnumber].group_invite.key = k;
|
|
||||||
Friends.list[friendnumber].group_invite.pending = true;
|
|
||||||
Friends.list[friendnumber].group_invite.length = length;
|
Friends.list[friendnumber].group_invite.length = length;
|
||||||
Friends.list[friendnumber].group_invite.type = type;
|
|
||||||
|
|
||||||
sound_notify(self, generic_message, NT_WNDALERT_2, NULL);
|
sound_notify(self, generic_message, NT_WNDALERT_2, NULL);
|
||||||
|
|
||||||
@ -540,7 +534,7 @@ static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, ui
|
|||||||
box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, "invites you to join group chat");
|
box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, "invites you to join group chat");
|
||||||
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to a group chat.", name);
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to a group chat.", name);
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/join\" to join the chat.");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/gaccept\" to join the chat.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Av Stuff */
|
/* Av Stuff */
|
||||||
@ -1104,7 +1098,6 @@ ToxWindow new_chat(Tox *m, uint32_t friendnum)
|
|||||||
ret.onMessage = &chat_onMessage;
|
ret.onMessage = &chat_onMessage;
|
||||||
ret.onConnectionChange = &chat_onConnectionChange;
|
ret.onConnectionChange = &chat_onConnectionChange;
|
||||||
ret.onTypingChange = & chat_onTypingChange;
|
ret.onTypingChange = & chat_onTypingChange;
|
||||||
ret.onGroupInvite = &chat_onGroupInvite;
|
|
||||||
ret.onNickChange = &chat_onNickChange;
|
ret.onNickChange = &chat_onNickChange;
|
||||||
ret.onStatusChange = &chat_onStatusChange;
|
ret.onStatusChange = &chat_onStatusChange;
|
||||||
ret.onStatusMessageChange = &chat_onStatusMessageChange;
|
ret.onStatusMessageChange = &chat_onStatusMessageChange;
|
||||||
@ -1113,6 +1106,7 @@ ToxWindow new_chat(Tox *m, uint32_t friendnum)
|
|||||||
ret.onFileControl = &chat_onFileControl;
|
ret.onFileControl = &chat_onFileControl;
|
||||||
ret.onFileRecv = &chat_onFileRecv;
|
ret.onFileRecv = &chat_onFileRecv;
|
||||||
ret.onReadReceipt = &chat_onReadReceipt;
|
ret.onReadReceipt = &chat_onReadReceipt;
|
||||||
|
ret.onGroupInvite = &chat_onGroupInvite;
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
ret.onInvite = &chat_onInvite;
|
ret.onInvite = &chat_onInvite;
|
||||||
|
@ -78,6 +78,46 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
|
|||||||
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, silent);
|
close_file_transfer(self, m, ft, TOX_FILE_CONTROL_CANCEL, msg, silent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmd_groupaccept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Friends.list[self->num].group_invite.length == 0) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending group invite");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *passwd = NULL;
|
||||||
|
uint16_t passwd_len = 0;
|
||||||
|
|
||||||
|
if (argc > 0) {
|
||||||
|
passwd = argv[1];
|
||||||
|
passwd_len = strlen(passwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_INVITE_ACCEPT err;
|
||||||
|
uint32_t groupnumber = tox_group_invite_accept(m, Friends.list[self->num].group_invite.data,
|
||||||
|
Friends.list[self->num].group_invite.length,
|
||||||
|
(uint8_t *) passwd, passwd_len, &err);
|
||||||
|
if (err != TOX_ERR_GROUP_INVITE_ACCEPT_OK) {
|
||||||
|
if (err == TOX_ERR_GROUP_INVITE_ACCEPT_TOO_LONG)
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to joing group: Password too long.");
|
||||||
|
else
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to joing group (error %d).", err);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init_groupchat_win(m, groupnumber, NULL, 0) == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize.");
|
||||||
|
tox_group_leave(m, groupnumber, NULL, 0, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
@ -92,53 +132,15 @@ void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tox_invite_friend(m, self->num, groupnum) == -1) {
|
TOX_ERR_GROUP_INVITE_FRIEND err;
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to invite contact to group.");
|
if (!tox_group_invite_friend(m, groupnum, self->num, &err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to invite contact to group (error %d).", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invited contact to Group %d.", groupnum);
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invited contact to Group %d.", groupnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
|
||||||
{
|
|
||||||
if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *groupkey = Friends.list[self->num].group_invite.key;
|
|
||||||
uint16_t length = Friends.list[self->num].group_invite.length;
|
|
||||||
uint8_t type = Friends.list[self->num].group_invite.type;
|
|
||||||
|
|
||||||
if (!Friends.list[self->num].group_invite.pending) {
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending group chat invite.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int groupnum = -1;
|
|
||||||
|
|
||||||
if (type == TOX_GROUPCHAT_TYPE_TEXT)
|
|
||||||
groupnum = tox_join_groupchat(m, self->num, (uint8_t *) groupkey, length);
|
|
||||||
#ifdef AUDIO
|
|
||||||
else
|
|
||||||
groupnum = toxav_join_av_groupchat(m, self->num, (uint8_t *) groupkey, length,
|
|
||||||
NULL, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (groupnum == -1) {
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (init_groupchat_win(prompt, m, groupnum, type) == -1) {
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize.");
|
|
||||||
tox_del_groupchat(m, groupnum);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "toxic.h"
|
#include "toxic.h"
|
||||||
|
|
||||||
|
void cmd_groupaccept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_groupinvite(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
|
||||||
void cmd_join_group(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
|
||||||
void cmd_savefile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_savefile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_sendfile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_sendfile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
|
||||||
|
109
src/execute.c
109
src/execute.c
@ -34,6 +34,8 @@
|
|||||||
#include "misc_tools.h"
|
#include "misc_tools.h"
|
||||||
#include "notify.h"
|
#include "notify.h"
|
||||||
|
|
||||||
|
#define MAX_NUM_ARGS 10 /* Includes command */
|
||||||
|
|
||||||
struct cmd_func {
|
struct cmd_func {
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*func)(WINDOW *w, ToxWindow *, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
void (*func)(WINDOW *w, ToxWindow *, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
@ -49,6 +51,7 @@ static struct cmd_func global_commands[] = {
|
|||||||
{ "/exit", cmd_quit },
|
{ "/exit", cmd_quit },
|
||||||
{ "/group", cmd_groupchat },
|
{ "/group", cmd_groupchat },
|
||||||
{ "/help", cmd_prompt_help },
|
{ "/help", cmd_prompt_help },
|
||||||
|
{ "/join", cmd_join },
|
||||||
{ "/log", cmd_log },
|
{ "/log", cmd_log },
|
||||||
{ "/myid", cmd_myid },
|
{ "/myid", cmd_myid },
|
||||||
{ "/nick", cmd_nick },
|
{ "/nick", cmd_nick },
|
||||||
@ -66,8 +69,8 @@ static struct cmd_func global_commands[] = {
|
|||||||
|
|
||||||
static struct cmd_func chat_commands[] = {
|
static struct cmd_func chat_commands[] = {
|
||||||
{ "/cancel", cmd_cancelfile },
|
{ "/cancel", cmd_cancelfile },
|
||||||
|
{ "/gaccept", cmd_groupaccept },
|
||||||
{ "/invite", cmd_groupinvite },
|
{ "/invite", cmd_groupinvite },
|
||||||
{ "/join", cmd_join_group },
|
|
||||||
{ "/savefile", cmd_savefile },
|
{ "/savefile", cmd_savefile },
|
||||||
{ "/sendfile", cmd_sendfile },
|
{ "/sendfile", cmd_sendfile },
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
@ -82,19 +85,96 @@ static struct cmd_func chat_commands[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct cmd_func group_commands[] = {
|
static struct cmd_func group_commands[] = {
|
||||||
{ "/title", cmd_set_title },
|
{ "/ban", cmd_ban },
|
||||||
|
{ "/chatid", cmd_chatid },
|
||||||
|
{ "/ignore", cmd_ignore },
|
||||||
|
{ "/kick", cmd_kick },
|
||||||
|
{ "/mod", cmd_mod },
|
||||||
|
{ "/passwd", cmd_set_passwd },
|
||||||
|
{ "/peerlimit", cmd_set_peerlimit },
|
||||||
|
{ "/privacy", cmd_set_privacy },
|
||||||
|
{ "/rejoin", cmd_rejoin },
|
||||||
|
{ "/silence", cmd_silence },
|
||||||
|
{ "/topic", cmd_set_topic },
|
||||||
|
{ "/unban", cmd_unban },
|
||||||
|
{ "/unignore", cmd_unignore },
|
||||||
|
{ "/unmod", cmd_unmod },
|
||||||
|
{ "/unsilence", cmd_unsilence },
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
{ "/mute", cmd_mute },
|
{ "/mute", cmd_mute },
|
||||||
{ "/sense", cmd_sense },
|
{ "/sense", cmd_sense },
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Parses input command and puts args into arg array.
|
#define NUM_SPECIAL_COMMANDS 14
|
||||||
Returns number of arguments on success, -1 on failure. */
|
static const char special_commands[NUM_SPECIAL_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||||
|
"/ban",
|
||||||
|
"/gaccept",
|
||||||
|
"/group",
|
||||||
|
"/ignore",
|
||||||
|
"/kick",
|
||||||
|
"/mod",
|
||||||
|
"/nick",
|
||||||
|
"/note",
|
||||||
|
"/passwd",
|
||||||
|
"/silence",
|
||||||
|
"/topic",
|
||||||
|
"/unignore",
|
||||||
|
"/unmod",
|
||||||
|
"/unsilence",
|
||||||
|
};
|
||||||
|
|
||||||
|
/* return true if input command is in the special_commands array. False otherwise.*/
|
||||||
|
static bool is_special_command(const char *input)
|
||||||
|
{
|
||||||
|
int s = char_find(0, input, ' ');
|
||||||
|
|
||||||
|
if (s == strlen(input))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_SPECIAL_COMMANDS; ++i) {
|
||||||
|
if (strncmp(input, special_commands[i], s) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parses commands in the special_commands array which take exactly one argument that may contain spaces.
|
||||||
|
* Unlike parse_command, this function does not split the input string at spaces.
|
||||||
|
*
|
||||||
|
* Returns number of arguments on success
|
||||||
|
* Returns -1 on failure
|
||||||
|
*/
|
||||||
|
static int parse_special_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
int len = strlen(input);
|
||||||
|
int s = char_find(0, input, ' ');
|
||||||
|
|
||||||
|
if (s + 1 >= len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy(args[0], input, s);
|
||||||
|
args[0][s++] = '\0'; /* increment to remove space after /command */
|
||||||
|
memcpy(args[1], input + s, len - s);
|
||||||
|
args[1][len - s] = '\0';
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parses input command and puts args (split by spaces) into args array.
|
||||||
|
*
|
||||||
|
* Returns number of arguments on success
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE])
|
static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
|
if (is_special_command(input))
|
||||||
|
return parse_special_command(w, self, input, args);
|
||||||
|
|
||||||
char *cmd = strdup(input);
|
char *cmd = strdup(input);
|
||||||
|
|
||||||
if (cmd == NULL)
|
if (cmd == NULL)
|
||||||
@ -132,11 +212,19 @@ static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*a
|
|||||||
strcpy(cmd, tmp); /* tmp will always fit inside cmd */
|
strcpy(cmd, tmp); /* tmp will always fit inside cmd */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ugly special case concatinates all args after arg1 for multi-word group passwords */
|
||||||
|
if (num_args > 2 && strcmp(args[0], "/join") == 0)
|
||||||
|
strcpy(args[2], input + strlen(args[0]) + 1 + strlen(args[1]) + 1);
|
||||||
|
|
||||||
free(cmd);
|
free(cmd);
|
||||||
return num_args;
|
return num_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Matches command to respective function. Returns 0 on match, 1 on no match */
|
/* Matches command to respective function.
|
||||||
|
*
|
||||||
|
* Returns 0 on match,
|
||||||
|
* Returns -1 on no match
|
||||||
|
*/
|
||||||
static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, struct cmd_func *commands,
|
static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, struct cmd_func *commands,
|
||||||
char (*args)[MAX_STR_SIZE])
|
char (*args)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
@ -149,7 +237,7 @@ static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, struct c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode)
|
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode)
|
||||||
@ -177,6 +265,7 @@ void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode)
|
|||||||
case GROUPCHAT_COMMAND_MODE:
|
case GROUPCHAT_COMMAND_MODE:
|
||||||
if (do_command(w, self, m, num_args, group_commands, args) == 0)
|
if (do_command(w, self, m, num_args, group_commands, args) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,13 +26,11 @@
|
|||||||
#include "toxic.h"
|
#include "toxic.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
|
||||||
#define MAX_NUM_ARGS 4 /* Includes command */
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GLOBAL_COMMAND_MODE,
|
GLOBAL_COMMAND_MODE,
|
||||||
CHAT_COMMAND_MODE,
|
CHAT_COMMAND_MODE,
|
||||||
GROUPCHAT_COMMAND_MODE,
|
GROUPCHAT_COMMAND_MODE,
|
||||||
};
|
} COMMAND_MODE;
|
||||||
|
|
||||||
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode);
|
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode);
|
||||||
|
|
||||||
|
@ -112,11 +112,11 @@ static void realloc_blocklist(int n)
|
|||||||
|
|
||||||
void kill_friendlist(void)
|
void kill_friendlist(void)
|
||||||
{
|
{
|
||||||
int i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < Friends.max_idx; ++i) {
|
for (i = 0; i < Friends.max_idx; ++i) {
|
||||||
if (Friends.list[i].active && Friends.list[i].group_invite.key != NULL)
|
if (Friends.list[i].group_invite.data != NULL)
|
||||||
free(Friends.list[i].group_invite.key);
|
free(Friends.list[i].group_invite.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
realloc_blocklist(0);
|
realloc_blocklist(0);
|
||||||
@ -496,8 +496,7 @@ static void friendlist_onFileRecv(ToxWindow *self, Tox *m, uint32_t num, uint32_
|
|||||||
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
|
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, uint8_t type, const char *group_pub_key,
|
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const char *data, size_t length)
|
||||||
uint16_t length)
|
|
||||||
{
|
{
|
||||||
if (num >= Friends.max_idx)
|
if (num >= Friends.max_idx)
|
||||||
return;
|
return;
|
||||||
@ -556,9 +555,6 @@ static void delete_friend(Tox *m, uint32_t f_num)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Friends.list[f_num].group_invite.key != NULL)
|
|
||||||
free(Friends.list[f_num].group_invite.key);
|
|
||||||
|
|
||||||
memset(&Friends.list[f_num], 0, sizeof(ToxicFriend));
|
memset(&Friends.list[f_num], 0, sizeof(ToxicFriend));
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
@ -35,11 +35,9 @@ struct LastOnline {
|
|||||||
char hour_min_str[TIME_STR_SIZE]; /* holds 12/24-hour time string e.g. "10:43 PM" */
|
char hour_min_str[TIME_STR_SIZE]; /* holds 12/24-hour time string e.g. "10:43 PM" */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GroupChatInvite {
|
struct GroupInvite {
|
||||||
char *key;
|
uint8_t *data;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
uint8_t type;
|
|
||||||
bool pending;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -57,7 +55,7 @@ typedef struct {
|
|||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
struct LastOnline last_online;
|
struct LastOnline last_online;
|
||||||
struct GroupChatInvite group_invite;
|
struct GroupInvite group_invite;
|
||||||
|
|
||||||
struct FileTransfer file_receiver[MAX_FILES];
|
struct FileTransfer file_receiver[MAX_FILES];
|
||||||
struct FileTransfer file_sender[MAX_FILES];
|
struct FileTransfer file_sender[MAX_FILES];
|
||||||
|
@ -192,7 +192,7 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd_add_helper(self, m, id_bin, msg);
|
cmd_add_helper(self, m, id_bin, msg);
|
||||||
} else { /* assume id is a username@domain address and do DNS lookup */
|
} else { /* assume id is a username@domain address */
|
||||||
dns3_lookup(self, m, id_bin, id, msg);
|
dns3_lookup(self, m, id_bin, id, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,42 +320,120 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please specify group type: text | audio");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group name required");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t type;
|
const char *tmp_name = argv[1];
|
||||||
|
int len = strlen(tmp_name);
|
||||||
|
|
||||||
if (!strcasecmp(argv[1], "audio"))
|
if (len == 0 || len > TOX_GROUP_MAX_GROUP_NAME_LENGTH) {
|
||||||
type = TOX_GROUPCHAT_TYPE_AV;
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid group name.");
|
||||||
else if (!strcasecmp(argv[1], "text"))
|
|
||||||
type = TOX_GROUPCHAT_TYPE_TEXT;
|
|
||||||
else {
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Valid group types are: text | audio");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int groupnum = -1;
|
char name[TOX_GROUP_MAX_GROUP_NAME_LENGTH];
|
||||||
|
|
||||||
if (type == TOX_GROUPCHAT_TYPE_TEXT)
|
if (argv[1][0] == '\"') { /* remove opening and closing quotes */
|
||||||
groupnum = tox_add_groupchat(m);
|
snprintf(name, sizeof(name), "%s", &argv[1][1]);
|
||||||
#ifdef AUDIO
|
len -= 2;
|
||||||
else
|
name[len] = '\0';
|
||||||
groupnum = toxav_add_av_groupchat(m, NULL, NULL);
|
} else {
|
||||||
#endif
|
snprintf(name, sizeof(name), "%s", argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_NEW err;
|
||||||
|
uint32_t groupnum = tox_group_new(m, TOX_GROUP_PRIVACY_STATE_PUBLIC, (uint8_t *) name, len, &err);
|
||||||
|
|
||||||
|
if (err != TOX_ERR_GROUP_NEW_OK) {
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_NEW_TOO_LONG: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group name length cannot exceed %d.", TOX_GROUP_MAX_GROUP_NAME_LENGTH);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_NEW_EMPTY: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group name cannot be empty.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize (error %d).", err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (groupnum == -1) {
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init_groupchat_win(prompt, m, groupnum, type) == -1) {
|
if (init_groupchat_win(m, groupnum, name, len) == -1) {
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize.");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize.");
|
||||||
tox_del_groupchat(m, groupnum);
|
tox_group_leave(m, groupnum, NULL, 0, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat [%d] created.", groupnum);
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Chat ID is required.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *chat_id = argv[1];
|
||||||
|
|
||||||
|
if (strlen(chat_id) != TOX_GROUP_CHAT_ID_SIZE * 2) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid chat ID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char id_bin[TOX_GROUP_CHAT_ID_SIZE] = {0};
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
char xch[3];
|
||||||
|
uint32_t x;
|
||||||
|
|
||||||
|
for (i = 0; i < TOX_GROUP_CHAT_ID_SIZE; ++i) {
|
||||||
|
xch[0] = chat_id[2 * i];
|
||||||
|
xch[1] = chat_id[2 * i + 1];
|
||||||
|
xch[2] = '\0';
|
||||||
|
|
||||||
|
if (sscanf(xch, "%02x", &x) != 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid chat ID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
id_bin[i] = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *passwd = NULL;
|
||||||
|
uint16_t passwd_len = 0;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
passwd = argv[2];
|
||||||
|
passwd_len = strlen(passwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_JOIN err;
|
||||||
|
uint32_t groupnum = tox_group_join(m, (uint8_t *) id_bin, (uint8_t *) passwd, passwd_len, &err);
|
||||||
|
|
||||||
|
if (err != TOX_ERR_GROUP_JOIN_OK) {
|
||||||
|
if (err == TOX_ERR_GROUP_JOIN_TOO_LONG)
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Password length cannot exceed %d.", TOX_GROUP_MAX_PASSWORD_SIZE);
|
||||||
|
else
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to join group (error %d).", err);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init_groupchat_win(m, groupnum, NULL, 0) == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize.");
|
||||||
|
tox_group_leave(m, groupnum, NULL, 0, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
@ -452,6 +530,7 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
|
|||||||
|
|
||||||
tox_self_set_name(m, (uint8_t *) nick, len, NULL);
|
tox_self_set_name(m, (uint8_t *) nick, len, NULL);
|
||||||
prompt_update_nick(prompt, nick);
|
prompt_update_nick(prompt, nick);
|
||||||
|
set_nick_all_groups(m, nick, len);
|
||||||
|
|
||||||
store_data(m, DATA_FILE);
|
store_data(m, DATA_FILE);
|
||||||
}
|
}
|
||||||
@ -463,18 +542,7 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv[1][0] != '\"') {
|
prompt_update_statusmessage(prompt, m, argv[1]);
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Note must be enclosed in quotes.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove opening and closing quotes */
|
|
||||||
char msg[MAX_STR_SIZE];
|
|
||||||
snprintf(msg, sizeof(msg), "%s", &argv[1][1]);
|
|
||||||
int len = strlen(msg) - 1;
|
|
||||||
msg[len] = '\0';
|
|
||||||
|
|
||||||
prompt_update_statusmessage(prompt, m, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_prompt_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_prompt_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
@ -549,6 +617,7 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
|
|||||||
|
|
||||||
tox_self_set_status(m, status);
|
tox_self_set_status(m, status);
|
||||||
prompt_update_status(prompt, status);
|
prompt_update_status(prompt, status);
|
||||||
|
set_status_all_groups(m, status);
|
||||||
|
|
||||||
if (have_note) {
|
if (have_note) {
|
||||||
if (argv[2][0] != '\"') {
|
if (argv[2][0] != '\"') {
|
||||||
|
@ -33,6 +33,7 @@ void cmd_clear(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE
|
|||||||
void cmd_connect(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_connect(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_groupchat(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_groupchat(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_nick(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_nick(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
@ -21,59 +21,590 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "toxic.h"
|
#include "toxic.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "line_info.h"
|
#include "line_info.h"
|
||||||
#include "misc_tools.h"
|
#include "misc_tools.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "groupchat.h"
|
||||||
|
|
||||||
void cmd_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
char title[MAX_STR_SIZE];
|
char chatid[TOX_GROUP_CHAT_ID_SIZE * 2 + 1] = {0};
|
||||||
|
char chat_public_key[TOX_GROUP_CHAT_ID_SIZE];
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_STATE_QUERIES err;
|
||||||
|
|
||||||
|
if (!tox_group_get_chat_id(m, self->num, (uint8_t *) chat_public_key, &err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve the Chat ID (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < TOX_GROUP_CHAT_ID_SIZE; ++i) {
|
||||||
|
char xx[3];
|
||||||
|
snprintf(xx, sizeof(xx), "%02X", chat_public_key[i] & 0xff);
|
||||||
|
strcat(chatid, xx);
|
||||||
|
}
|
||||||
|
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", chatid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer name must be specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *nick = argv[1];
|
||||||
|
int peernum = group_get_nick_peernumber(self->num, nick);
|
||||||
|
|
||||||
|
if (peernum == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid peer name '%s'.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_TOGGLE_IGNORE err;
|
||||||
|
if (!tox_group_toggle_ignore(m, self->num, peernum, true, &err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to ignore %s (error %d).", nick, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char timefrmt[TIME_STR_SIZE];
|
||||||
|
get_time_str(timefrmt, sizeof(timefrmt));
|
||||||
|
|
||||||
|
line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- Ignoring %s", nick);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_kickban_helper(ToxWindow *self, Tox *m, const char *nick, bool set_ban)
|
||||||
|
{
|
||||||
|
int peernumber = group_get_nick_peernumber(self->num, nick);
|
||||||
|
|
||||||
|
if (peernumber == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid peer name '%s'.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *type_str = set_ban ? "ban" : "kick";
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_MOD_REMOVE_PEER err;
|
||||||
|
tox_group_mod_remove_peer(m, self->num, (uint32_t) peernumber, set_ban, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_MOD_REMOVE_PEER_OK: {
|
||||||
|
type_str = set_ban ? "banned" : "kicked";
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, RED, "You have %s %s from the group.", type_str, nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_MOD_REMOVE_PEER_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to %s %s.", type_str, nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to %s %s from the group (error %d).", type_str, nick, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_kick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer name must be specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_kickban_helper(self, m, argv[1], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_ban(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
TOX_ERR_GROUP_BAN_QUERY err;
|
||||||
|
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
int tlen = tox_group_get_title(m, self->num, (uint8_t *) title, TOX_MAX_NAME_LENGTH);
|
size_t num_banned = tox_group_ban_get_list_size(m, self->num, &err);
|
||||||
|
|
||||||
if (tlen != -1) {
|
if (err != TOX_ERR_GROUP_BAN_QUERY_OK) {
|
||||||
title[tlen] = '\0';
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to get the ban list size (error %d).", err);
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title is set to: %s", title);
|
return;
|
||||||
} else {
|
}
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title is not set");
|
|
||||||
|
if (num_banned == 0) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Ban list is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ban_list[num_banned];
|
||||||
|
|
||||||
|
if (!tox_group_ban_get_list(m, self->num, ban_list, &err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to get the ban list (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_banned; ++i) {
|
||||||
|
uint16_t id = ban_list[i];
|
||||||
|
size_t len = tox_group_ban_get_name_size(m, self->num, id, &err);
|
||||||
|
|
||||||
|
if (err != TOX_ERR_GROUP_BAN_QUERY_OK) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve name length for ban %d (error %d).", id, err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char tmp_nick[len];
|
||||||
|
|
||||||
|
if (!tox_group_ban_get_name(m, self->num, id, (uint8_t *) tmp_nick, &err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve name for ban %d (error %d).", id, err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char nick[len + 1];
|
||||||
|
copy_tox_str(nick, sizeof(nick), tmp_nick, len);
|
||||||
|
|
||||||
|
uint64_t time_set = tox_group_ban_get_time_set(m, self->num, id, &err);
|
||||||
|
|
||||||
|
if (err != TOX_ERR_GROUP_BAN_QUERY_OK) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve timestamp for ban %d (error %d).", id, err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tm tm_set = *localtime((const time_t *) &time_set);
|
||||||
|
char time_str[64];
|
||||||
|
strftime(time_str, sizeof(time_str), "%e %b %Y %H:%M:%S%p", &tm_set);
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "ID %d : %s [Set:%s]", id, nick, time_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv[1][0] != '\"') {
|
cmd_kickban_helper(self, m, argv[1], true);
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Title must be enclosed in quotes.");
|
}
|
||||||
|
|
||||||
|
void cmd_unban(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Ban ID must be specified.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove opening and closing quotes */
|
int ban_id = atoi(argv[1]);
|
||||||
snprintf(title, sizeof(title), "%s", &argv[1][1]);
|
|
||||||
int len = strlen(title) - 1;
|
|
||||||
title[len] = '\0';
|
|
||||||
|
|
||||||
if (tox_group_set_title(m, self->num, (uint8_t *) title, len) != 0) {
|
if (ban_id == 0 && strcmp(argv[1], "0")) {
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set title.");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Ban ID must be a non-negative interger.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_window_title(self, title, len);
|
TOX_ERR_GROUP_MOD_REMOVE_BAN err;
|
||||||
|
tox_group_mod_remove_ban(m, self->num, ban_id, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_MOD_REMOVE_BAN_OK: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Ban list entry with id %d has been removed.", ban_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_MOD_REMOVE_BAN_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to unban peers.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_MOD_REMOVE_BAN_FAIL_ACTION: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Ban ID does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to remove ban list entry (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_mod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer name must be specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *nick = argv[1];
|
||||||
|
int peernumber = group_get_nick_peernumber(self->num, nick);
|
||||||
|
|
||||||
|
if (peernumber == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid peer name '%s'.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_MOD_SET_ROLE err;
|
||||||
|
tox_group_mod_set_role(m, self->num, peernumber, TOX_GROUP_ROLE_MODERATOR, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, "You have promoted %s to moderator.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to promote moderators.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "This peer is already a moderator.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to promote peer to moderator (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_unmod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer name must be specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *nick = argv[1];
|
||||||
|
int peernumber = group_get_nick_peernumber(self->num, nick);
|
||||||
|
|
||||||
|
if (peernumber == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid peer name '%s'.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tox_group_peer_get_role(m, self->num, peernumber, NULL) != TOX_GROUP_ROLE_MODERATOR) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s is not a moderator", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_MOD_SET_ROLE err;
|
||||||
|
tox_group_mod_set_role(m, self->num, peernumber, TOX_GROUP_ROLE_USER, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, "You have revoked moderator powers from %s.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Nice try.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to revoke moderator powers from %s (error %d).", nick, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_set_passwd(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
const char *passwd = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (argc > 0) {
|
||||||
|
passwd = argv[1];
|
||||||
|
len = strlen(passwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_FOUNDER_SET_PASSWORD err;
|
||||||
|
tox_group_founder_set_password(m, self->num, (uint8_t *) passwd, len, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK: {
|
||||||
|
if (len > 0)
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Password has been set to %s.", passwd);
|
||||||
|
else
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Password has been unset.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Password length must not exceed %d.", TOX_GROUP_MAX_PASSWORD_SIZE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the password.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set password (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_set_peerlimit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
int maxpeers = 0;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
TOX_ERR_GROUP_STATE_QUERIES err;
|
||||||
|
uint32_t maxpeers = tox_group_get_peer_limit(m, self->num, &err);
|
||||||
|
|
||||||
|
if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve peer limit (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer limit is set to %d", maxpeers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxpeers = atoi(argv[1]);
|
||||||
|
|
||||||
|
if (maxpeers <= 0) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer limit must be a value greater than 0.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT err;
|
||||||
|
tox_group_founder_set_peer_limit(m, self->num, maxpeers, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer limit has been set to %d.", maxpeers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the peer limit.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set the peer limit (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_set_privacy(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
const char *pstate_str = NULL;
|
||||||
|
TOX_GROUP_PRIVACY_STATE privacy_state;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
TOX_ERR_GROUP_STATE_QUERIES err;
|
||||||
|
privacy_state = tox_group_get_privacy_state(m, self->num, &err);
|
||||||
|
|
||||||
|
if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve privacy state (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pstate_str = privacy_state == TOX_GROUP_PRIVACY_STATE_PRIVATE ? "private" : "public";
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Privacy state is set to %s.", pstate_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pstate_str = argv[1];
|
||||||
|
|
||||||
|
if (strcasecmp(pstate_str, "private") != 0 && strcasecmp(pstate_str, "public") != 0) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Privacy state must be \"private\" or \"public\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
privacy_state = strcasecmp(pstate_str, "private") == 0 ? TOX_GROUP_PRIVACY_STATE_PRIVATE : TOX_GROUP_PRIVACY_STATE_PUBLIC;
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE err;
|
||||||
|
tox_group_founder_set_privacy_state(m, self->num, privacy_state, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Privacy state has been set to %s.", pstate_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the privacy state.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error setting privacy state (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_silence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer name must be specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *nick = argv[1];
|
||||||
|
int peernumber = group_get_nick_peernumber(self->num, nick);
|
||||||
|
|
||||||
|
if (peernumber == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid peer name '%s'.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_MOD_SET_ROLE err;
|
||||||
|
tox_group_mod_set_role(m, self->num, peernumber, TOX_GROUP_ROLE_OBSERVER, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, "You have silenced %s", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to silence %s.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to silence %s (error %d).", nick, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_unsilence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer name must be specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *nick = argv[1];
|
||||||
|
int peernumber = group_get_nick_peernumber(self->num, nick);
|
||||||
|
|
||||||
|
if (peernumber == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid peer name '%s'.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tox_group_peer_get_role(m, self->num, peernumber, NULL) != TOX_GROUP_ROLE_OBSERVER) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s is not silenced.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_MOD_SET_ROLE err;
|
||||||
|
tox_group_mod_set_role(m, self->num, peernumber, TOX_GROUP_ROLE_USER, &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 1, BLUE, "You have unsilenced %s.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to unsilence %s.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unsilence %s (error %d).", nick, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_rejoin(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
TOX_ERR_GROUP_RECONNECT err;
|
||||||
|
if (!tox_group_reconnect(m, self->num, &err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to rejoin group (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Reconnecting to group...");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
TOX_ERR_GROUP_STATE_QUERIES err;
|
||||||
|
size_t tlen = tox_group_get_topic_size(m, self->num, &err);
|
||||||
|
|
||||||
|
if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve topic length (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tlen > 0) {
|
||||||
|
char cur_topic[tlen];
|
||||||
|
|
||||||
|
if (!tox_group_get_topic(m, self->num, (uint8_t *) cur_topic, &err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve topic (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_topic[tlen] = '\0';
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Topic is set to: %s", cur_topic);
|
||||||
|
} else {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Topic is not set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *topic = argv[1];
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_TOPIC_SET err;
|
||||||
|
tox_group_set_topic(m, self->num, (uint8_t *) topic, strlen(topic), &err);
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case TOX_ERR_GROUP_TOPIC_SET_OK: {
|
||||||
|
/* handled below switch */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_TOPIC_SET_TOO_LONG: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Topic length must not exceed %d.", TOX_GROUP_MAX_TOPIC_LENGTH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case TOX_ERR_GROUP_TOPIC_SET_PERMISSIONS: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the topic.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set the topic (error %d).", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char timefrmt[TIME_STR_SIZE];
|
char timefrmt[TIME_STR_SIZE];
|
||||||
char selfnick[TOX_MAX_NAME_LENGTH];
|
|
||||||
|
|
||||||
get_time_str(timefrmt, sizeof(timefrmt));
|
get_time_str(timefrmt, sizeof(timefrmt));
|
||||||
|
|
||||||
tox_self_get_name(m, (uint8_t *) selfnick);
|
TOX_ERR_GROUP_SELF_QUERY sn_err;
|
||||||
size_t sn_len = tox_self_get_name_size(m);
|
size_t sn_len = tox_group_self_get_name_size(m, self->num, &sn_err);
|
||||||
|
char selfnick[sn_len];
|
||||||
|
|
||||||
|
if (!tox_group_self_get_name(m, self->num, (uint8_t *) selfnick, &sn_err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve your own name (error %d).", sn_err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
selfnick[sn_len] = '\0';
|
selfnick[sn_len] = '\0';
|
||||||
|
|
||||||
line_info_add(self, timefrmt, selfnick, NULL, NAME_CHANGE, 0, 0, " set the group title to: %s", title);
|
line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, MAGENTA, "-!- You set the topic to: %s.", topic);
|
||||||
|
|
||||||
char tmp_event[MAX_STR_SIZE];
|
char tmp_event[MAX_STR_SIZE];
|
||||||
snprintf(tmp_event, sizeof(tmp_event), "set title to %s", title);
|
snprintf(tmp_event, sizeof(tmp_event), "set topic to %s", topic);
|
||||||
write_to_log(tmp_event, selfnick, self->chatwin->log, true);
|
write_to_log(tmp_event, selfnick, self->chatwin->log, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer must be specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *nick = argv[1];
|
||||||
|
int peernum = group_get_nick_peernumber(self->num, nick);
|
||||||
|
|
||||||
|
if (peernum == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid peer name '%s'.", nick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_GROUP_TOGGLE_IGNORE err;
|
||||||
|
if (!tox_group_toggle_ignore(m, self->num, peernum, false, &err)) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unignore %s (error %d).", nick, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char timefrmt[TIME_STR_SIZE];
|
||||||
|
get_time_str(timefrmt, sizeof(timefrmt));
|
||||||
|
|
||||||
|
line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- You are no longer ignoring %s", nick);
|
||||||
|
}
|
||||||
|
@ -26,6 +26,21 @@
|
|||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "toxic.h"
|
#include "toxic.h"
|
||||||
|
|
||||||
void cmd_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_ban(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_kick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_mod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_prune(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_set_passwd(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_set_peerlimit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_set_privacy(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_rejoin(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_silence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_unsilence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_unban(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_unmod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
|
||||||
#endif /* GROUP_COMMANDS_H */
|
#endif /* GROUP_COMMANDS_H */
|
||||||
|
955
src/groupchat.c
955
src/groupchat.c
File diff suppressed because it is too large
Load Diff
@ -59,28 +59,26 @@ struct GAudio {
|
|||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint32_t groupnumber;
|
||||||
int chatwin;
|
int chatwin;
|
||||||
bool active;
|
bool active;
|
||||||
uint8_t type;
|
bool is_connected;
|
||||||
int num_peers;
|
|
||||||
int side_pos; /* current position of the sidebar - used for scrolling up and down */
|
int side_pos; /* current position of the sidebar - used for scrolling up and down */
|
||||||
uint64_t start_time;
|
uint32_t num_peers;
|
||||||
uint8_t *peer_names;
|
uint8_t *peer_names;
|
||||||
uint8_t *oldpeer_names;
|
|
||||||
uint16_t *peer_name_lengths;
|
uint16_t *peer_name_lengths;
|
||||||
uint16_t *oldpeer_name_lengths;
|
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
struct GAudio audio;
|
struct GAudio audio;
|
||||||
#endif
|
#endif
|
||||||
} GroupChat;
|
} GroupChat;
|
||||||
|
|
||||||
void close_groupchat(ToxWindow *self, Tox *m, int groupnum);
|
void close_groupchat(ToxWindow *self, Tox *m, uint32_t groupnum);
|
||||||
int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum, uint8_t type);
|
int init_groupchat_win(Tox *m, uint32_t groupnum, const char *groupname, size_t length);
|
||||||
|
void set_nick_all_groups(Tox *m, const char *nick, size_t length);
|
||||||
|
void set_status_all_groups(Tox *m, uint8_t status);
|
||||||
|
int group_get_nick_peernumber(uint32_t groupnum, const char *nick);
|
||||||
|
|
||||||
/* destroys and re-creates groupchat window with or without the peerlist */
|
/* destroys and re-creates groupchat window with or without the peerlist */
|
||||||
void redraw_groupchat_win(ToxWindow *self);
|
void redraw_groupchat_win(ToxWindow *self);
|
||||||
|
|
||||||
ToxWindow new_group_chat(Tox *m, int groupnum);
|
|
||||||
|
|
||||||
#endif /* #define GROUPCHAT_H */
|
#endif /* #define GROUPCHAT_H */
|
||||||
|
41
src/help.c
41
src/help.c
@ -150,9 +150,10 @@ static void help_draw_global(ToxWindow *self)
|
|||||||
wprintw(win, " /connect <ip> <port> <key> : Manually connect to a DHT node\n");
|
wprintw(win, " /connect <ip> <port> <key> : Manually connect to a DHT node\n");
|
||||||
wprintw(win, " /status <type> <msg> : Set status with optional note\n");
|
wprintw(win, " /status <type> <msg> : Set status with optional note\n");
|
||||||
wprintw(win, " /note <msg> : Set a personal note\n");
|
wprintw(win, " /note <msg> : Set a personal note\n");
|
||||||
|
wprintw(win, " /group : Create a group chat\n");
|
||||||
|
wprintw(win, " /join <chat id> <passwd> : Join a group chat with optional password\n");
|
||||||
wprintw(win, " /nick <nick> : Set your nickname\n");
|
wprintw(win, " /nick <nick> : Set your nickname\n");
|
||||||
wprintw(win, " /log <on> or <off> : Enable/disable logging\n");
|
wprintw(win, " /log <on> or <off> : Enable/disable logging\n");
|
||||||
wprintw(win, " /group <type> : Create a group chat where type: text | audio\n");
|
|
||||||
wprintw(win, " /myid : Print your Tox ID\n");
|
wprintw(win, " /myid : Print your Tox ID\n");
|
||||||
wprintw(win, " /clear : Clear window history\n");
|
wprintw(win, " /clear : Clear window history\n");
|
||||||
wprintw(win, " /close : Close the current chat window\n");
|
wprintw(win, " /close : Close the current chat window\n");
|
||||||
@ -183,8 +184,7 @@ static void help_draw_chat(ToxWindow *self)
|
|||||||
wprintw(win, "Chat Commands:\n");
|
wprintw(win, "Chat Commands:\n");
|
||||||
wattroff(win, A_BOLD | COLOR_PAIR(RED));
|
wattroff(win, A_BOLD | COLOR_PAIR(RED));
|
||||||
|
|
||||||
wprintw(win, " /invite <n> : Invite contact to a group chat\n");
|
wprintw(win, " /gaccept <password> : Accept a group invite with optional password\n");
|
||||||
wprintw(win, " /join : Join a pending group chat\n");
|
|
||||||
wprintw(win, " /sendfile <path> : Send a file\n");
|
wprintw(win, " /sendfile <path> : Send a file\n");
|
||||||
wprintw(win, " /savefile <id> : Receive a file\n");
|
wprintw(win, " /savefile <id> : Receive a file\n");
|
||||||
wprintw(win, " /cancel <type> <id> : Cancel file transfer where type: in|out\n");
|
wprintw(win, " /cancel <type> <id> : Cancel file transfer where type: in|out\n");
|
||||||
@ -243,7 +243,30 @@ static void help_draw_group(ToxWindow *self)
|
|||||||
wprintw(win, "Group commands:\n");
|
wprintw(win, "Group commands:\n");
|
||||||
wattroff(win, A_BOLD | COLOR_PAIR(RED));
|
wattroff(win, A_BOLD | COLOR_PAIR(RED));
|
||||||
|
|
||||||
wprintw(win, " /title <msg> : Set group title (show current title if no msg)\n\n");
|
wprintw(win, " /chatid : Print the group chat id to share with others\n");
|
||||||
|
wprintw(win, " /ignore <nick> : Ignore peer\n");
|
||||||
|
wprintw(win, " /unignore <nick> : Unignore peer \n");
|
||||||
|
wprintw(win, " /rejoin : Rejoin the group\n");
|
||||||
|
wprintw(win, " /topic <msg> : Set group topic (show current topic if no msg)\n");
|
||||||
|
wprintw(win, " /whisper <nick> <msg> : Send private message to nick\n");
|
||||||
|
|
||||||
|
wattron(win, A_BOLD);
|
||||||
|
wprintw(win, " Moderator commands:\n");
|
||||||
|
wattroff(win, A_BOLD);
|
||||||
|
wprintw(win, " /kick <nick> : Kick peer\n");
|
||||||
|
wprintw(win, " /ban <nick> : Ban peer (leave nick blank to see ban list)\n");
|
||||||
|
wprintw(win, " /unban <Ban ID> : Unban entry\n");
|
||||||
|
wprintw(win, " /silence <nick> : Silences peer for the entire group\n");
|
||||||
|
wprintw(win, " /unsilence <nick> : Unsilences peer\n");
|
||||||
|
|
||||||
|
wattron(win, A_BOLD);
|
||||||
|
wprintw(win, " Founder commands:\n");
|
||||||
|
wattroff(win, A_BOLD);
|
||||||
|
wprintw(win, " /mod <nick> : Promote peer to moderator\n");
|
||||||
|
wprintw(win, " /unmod <nick> : Demote moderator to normal user\n");
|
||||||
|
wprintw(win, " /passwd <password> : Set group password (leave blank to unset)\n");
|
||||||
|
wprintw(win, " /peerlimit <num> : Set group peer limit\n");
|
||||||
|
wprintw(win, " /privacy <state> : Set group privacy state: private|public\n");
|
||||||
|
|
||||||
help_draw_bottom_menu(win);
|
help_draw_bottom_menu(win);
|
||||||
|
|
||||||
@ -283,24 +306,24 @@ void help_onKey(ToxWindow *self, wint_t key)
|
|||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
help_init_window(self, 19, 80);
|
help_init_window(self, 18, 80);
|
||||||
#else
|
#else
|
||||||
help_init_window(self, 9, 80);
|
help_init_window(self, 8, 80);
|
||||||
#endif
|
#endif
|
||||||
self->help->type = HELP_CHAT;
|
self->help->type = HELP_CHAT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g':
|
case 'g':
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
help_init_window(self, 24, 80);
|
help_init_window(self, 25, 80);
|
||||||
#else
|
#else
|
||||||
help_init_window(self, 20, 80);
|
help_init_window(self, 21, 80);
|
||||||
#endif
|
#endif
|
||||||
self->help->type = HELP_GLOBAL;
|
self->help->type = HELP_GLOBAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
help_init_window(self, 6, 80);
|
help_init_window(self, 23, 80);
|
||||||
self->help->type = HELP_GROUP;
|
self->help->type = HELP_GROUP;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -166,6 +166,11 @@ void line_info_add(ToxWindow *self, const char *timestr, const char *name1, cons
|
|||||||
len += strlen(user_settings->line_normal) + 3;
|
len += strlen(user_settings->line_normal) + 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IN_PRVT_MSG:
|
||||||
|
case OUT_PRVT_MSG:
|
||||||
|
len += strlen(user_settings->line_special) + 3;
|
||||||
|
break;
|
||||||
|
|
||||||
case CONNECTION:
|
case CONNECTION:
|
||||||
len += strlen(user_settings->line_join) + 2;
|
len += strlen(user_settings->line_join) + 2;
|
||||||
break;
|
break;
|
||||||
@ -305,6 +310,8 @@ void line_info_print(ToxWindow *self)
|
|||||||
case OUT_MSG_READ:
|
case OUT_MSG_READ:
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case IN_MSG:
|
case IN_MSG:
|
||||||
|
case IN_PRVT_MSG:
|
||||||
|
case OUT_PRVT_MSG:
|
||||||
wattron(win, COLOR_PAIR(BLUE));
|
wattron(win, COLOR_PAIR(BLUE));
|
||||||
wprintw(win, "%s ", line->timestr);
|
wprintw(win, "%s ", line->timestr);
|
||||||
wattroff(win, COLOR_PAIR(BLUE));
|
wattroff(win, COLOR_PAIR(BLUE));
|
||||||
@ -317,7 +324,10 @@ void line_info_print(ToxWindow *self)
|
|||||||
nameclr = CYAN;
|
nameclr = CYAN;
|
||||||
|
|
||||||
wattron(win, COLOR_PAIR(nameclr));
|
wattron(win, COLOR_PAIR(nameclr));
|
||||||
wprintw(win, "%s %s: ", user_settings->line_normal, line->name1);
|
wprintw(win, "%s %s: ",(type != OUT_PRVT_MSG && type != IN_PRVT_MSG) ?
|
||||||
|
user_settings->line_normal :
|
||||||
|
user_settings->line_special,
|
||||||
|
line->name1);
|
||||||
wattroff(win, COLOR_PAIR(nameclr));
|
wattroff(win, COLOR_PAIR(nameclr));
|
||||||
|
|
||||||
if (line->msg[0] == '>')
|
if (line->msg[0] == '>')
|
||||||
|
@ -35,10 +35,12 @@ enum {
|
|||||||
SYS_MSG,
|
SYS_MSG,
|
||||||
IN_MSG,
|
IN_MSG,
|
||||||
OUT_MSG,
|
OUT_MSG,
|
||||||
OUT_MSG_READ, /* for sent messages that have received a read reply. don't set this with line_info_add */
|
OUT_MSG_READ, /* for sent messages that have received a read reply. */
|
||||||
IN_ACTION,
|
IN_ACTION,
|
||||||
OUT_ACTION,
|
OUT_ACTION,
|
||||||
OUT_ACTION_READ, /* same as OUT_MSG_READ but for actions */
|
OUT_ACTION_READ, /* same as OUT_MSG_READ but for actions */
|
||||||
|
IN_PRVT_MSG, /* PRVT should only be used for groups */
|
||||||
|
OUT_PRVT_MSG,
|
||||||
PROMPT,
|
PROMPT,
|
||||||
CONNECTION,
|
CONNECTION,
|
||||||
DISCONNECTION,
|
DISCONNECTION,
|
||||||
|
@ -287,11 +287,19 @@ size_t get_nick_truncate(Tox *m, char *buf, uint32_t friendnum)
|
|||||||
/* same as get_nick_truncate but for groupchats */
|
/* same as get_nick_truncate but for groupchats */
|
||||||
int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum)
|
int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum)
|
||||||
{
|
{
|
||||||
int len = tox_group_peername(m, groupnum, peernum, (uint8_t *) buf);
|
TOX_ERR_GROUP_PEER_QUERY err;
|
||||||
|
size_t len = tox_group_peer_get_name_size(m, groupnum, peernum, &err);
|
||||||
|
|
||||||
if (len == -1) {
|
if (err != TOX_ERR_GROUP_PEER_QUERY_OK) {
|
||||||
strcpy(buf, UNKNOWN_NAME);
|
strcpy(buf, UNKNOWN_NAME);
|
||||||
len = strlen(UNKNOWN_NAME);
|
len = strlen(UNKNOWN_NAME);
|
||||||
|
} else {
|
||||||
|
tox_group_peer_get_name(m, groupnum, peernum, (uint8_t *) buf, &err);
|
||||||
|
|
||||||
|
if (err != TOX_ERR_GROUP_PEER_QUERY_OK) {
|
||||||
|
strcpy(buf, UNKNOWN_NAME);
|
||||||
|
len = strlen(UNKNOWN_NAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
|
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
|
||||||
@ -301,13 +309,18 @@ int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copies data to msg buffer.
|
/* copies data to msg buffer.
|
||||||
returns length of msg, which will be no larger than size-1 */
|
returns length of msg.
|
||||||
|
returns 0 and nulls msg if length is too big for buffer size */
|
||||||
size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length)
|
size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length)
|
||||||
{
|
{
|
||||||
size_t len = MIN(length, size - 1);
|
if (length > size - 1) {
|
||||||
memcpy(msg, data, len);
|
msg[0] = '\0';
|
||||||
msg[len] = '\0';
|
return 0;
|
||||||
return len;
|
}
|
||||||
|
|
||||||
|
memcpy(msg, data, length);
|
||||||
|
msg[length] = '\0';
|
||||||
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns index of the first instance of ch in s starting at idx.
|
/* returns index of the first instance of ch in s starting at idx.
|
||||||
|
@ -108,7 +108,8 @@ size_t get_nick_truncate(Tox *m, char *buf, uint32_t friendnum);
|
|||||||
int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum);
|
int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum);
|
||||||
|
|
||||||
/* copies data to msg buffer.
|
/* copies data to msg buffer.
|
||||||
returns length of msg, which will be no larger than size-1 */
|
returns length of msg.
|
||||||
|
returns 0 and nulls msg if length is too big for buffer size */
|
||||||
size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length);
|
size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length);
|
||||||
|
|
||||||
/* returns index of the first instance of ch in s starting at idx.
|
/* returns index of the first instance of ch in s starting at idx.
|
||||||
|
@ -51,9 +51,9 @@ extern FriendsList Friends;
|
|||||||
FriendRequests FrndRequests;
|
FriendRequests FrndRequests;
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
#define AC_NUM_GLOB_COMMANDS 18
|
#define AC_NUM_GLOB_COMMANDS 19
|
||||||
#else
|
#else
|
||||||
#define AC_NUM_GLOB_COMMANDS 16
|
#define AC_NUM_GLOB_COMMANDS 17
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
/* Array of global command names used for tab completion. */
|
/* Array of global command names used for tab completion. */
|
||||||
@ -67,6 +67,7 @@ static const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
|
|||||||
{ "/exit" },
|
{ "/exit" },
|
||||||
{ "/group" },
|
{ "/group" },
|
||||||
{ "/help" },
|
{ "/help" },
|
||||||
|
{ "/join" },
|
||||||
{ "/log" },
|
{ "/log" },
|
||||||
{ "/myid" },
|
{ "/myid" },
|
||||||
{ "/nick" },
|
{ "/nick" },
|
||||||
|
@ -62,6 +62,7 @@ static struct ui_strings {
|
|||||||
const char* line_quit;
|
const char* line_quit;
|
||||||
const char* line_alert;
|
const char* line_alert;
|
||||||
const char* line_normal;
|
const char* line_normal;
|
||||||
|
const char* line_special;
|
||||||
|
|
||||||
const char* mplex_away;
|
const char* mplex_away;
|
||||||
const char* mplex_away_note;
|
const char* mplex_away_note;
|
||||||
@ -82,6 +83,7 @@ static struct ui_strings {
|
|||||||
"line_quit",
|
"line_quit",
|
||||||
"line_alert",
|
"line_alert",
|
||||||
"line_normal",
|
"line_normal",
|
||||||
|
"line_special",
|
||||||
"mplex_away",
|
"mplex_away",
|
||||||
"mplex_away_note",
|
"mplex_away_note",
|
||||||
};
|
};
|
||||||
@ -104,6 +106,7 @@ static void ui_defaults(struct user_settings* settings)
|
|||||||
snprintf(settings->line_quit, LINE_HINT_MAX + 1, "%s", LINE_QUIT);
|
snprintf(settings->line_quit, LINE_HINT_MAX + 1, "%s", LINE_QUIT);
|
||||||
snprintf(settings->line_alert, LINE_HINT_MAX + 1, "%s", LINE_ALERT);
|
snprintf(settings->line_alert, LINE_HINT_MAX + 1, "%s", LINE_ALERT);
|
||||||
snprintf(settings->line_normal, LINE_HINT_MAX + 1, "%s", LINE_NORMAL);
|
snprintf(settings->line_normal, LINE_HINT_MAX + 1, "%s", LINE_NORMAL);
|
||||||
|
snprintf(settings->line_special, LINE_HINT_MAX + 1, "%s", LINE_SPECIAL);
|
||||||
|
|
||||||
settings->mplex_away = MPLEX_ON;
|
settings->mplex_away = MPLEX_ON;
|
||||||
snprintf (settings->mplex_away_note,
|
snprintf (settings->mplex_away_note,
|
||||||
@ -321,6 +324,9 @@ int settings_load(struct user_settings *s, const char *patharg)
|
|||||||
if ( config_setting_lookup_string(setting, ui_strings.line_normal, &str) ) {
|
if ( config_setting_lookup_string(setting, ui_strings.line_normal, &str) ) {
|
||||||
snprintf(s->line_normal, sizeof(s->line_normal), "%s", str);
|
snprintf(s->line_normal, sizeof(s->line_normal), "%s", str);
|
||||||
}
|
}
|
||||||
|
if ( config_setting_lookup_string(setting, ui_strings.line_special, &str) ) {
|
||||||
|
snprintf(s->line_special, sizeof(s->line_special), "%s", str);
|
||||||
|
}
|
||||||
|
|
||||||
config_setting_lookup_bool (setting, ui_strings.mplex_away, &s->mplex_away);
|
config_setting_lookup_bool (setting, ui_strings.mplex_away, &s->mplex_away);
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ struct user_settings {
|
|||||||
char line_quit[LINE_HINT_MAX + 1];
|
char line_quit[LINE_HINT_MAX + 1];
|
||||||
char line_alert[LINE_HINT_MAX + 1];
|
char line_alert[LINE_HINT_MAX + 1];
|
||||||
char line_normal[LINE_HINT_MAX + 1];
|
char line_normal[LINE_HINT_MAX + 1];
|
||||||
|
char line_special[LINE_HINT_MAX + 1];
|
||||||
|
|
||||||
char download_path[PATH_MAX];
|
char download_path[PATH_MAX];
|
||||||
char chatlogs_path[PATH_MAX];
|
char chatlogs_path[PATH_MAX];
|
||||||
@ -104,6 +105,7 @@ enum {
|
|||||||
#define LINE_QUIT "<--"
|
#define LINE_QUIT "<--"
|
||||||
#define LINE_ALERT "-!-"
|
#define LINE_ALERT "-!-"
|
||||||
#define LINE_NORMAL "---"
|
#define LINE_NORMAL "---"
|
||||||
|
#define LINE_SPECIAL ">>>"
|
||||||
#define TIMESTAMP_DEFAULT "%H:%M:%S"
|
#define TIMESTAMP_DEFAULT "%H:%M:%S"
|
||||||
#define LOG_TIMESTAMP_DEFAULT "%Y/%m/%d [%H:%M:%S]"
|
#define LOG_TIMESTAMP_DEFAULT "%Y/%m/%d [%H:%M:%S]"
|
||||||
#define MPLEX_AWAY_NOTE "Detached from screen"
|
#define MPLEX_AWAY_NOTE "Detached from screen"
|
||||||
|
36
src/toxic.c
36
src/toxic.c
@ -47,6 +47,7 @@
|
|||||||
#include "toxic.h"
|
#include "toxic.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "friendlist.h"
|
#include "friendlist.h"
|
||||||
|
#include "groupchat.h"
|
||||||
#include "prompt.h"
|
#include "prompt.h"
|
||||||
#include "misc_tools.h"
|
#include "misc_tools.h"
|
||||||
#include "file_transfers.h"
|
#include "file_transfers.h"
|
||||||
@ -251,7 +252,7 @@ static void print_init_messages(ToxWindow *toxwin)
|
|||||||
line_info_add(toxwin, NULL, NULL, NULL, SYS_MSG, 0, 0, init_messages.msgs[i]);
|
line_info_add(toxwin, NULL, NULL, NULL, SYS_MSG, 0, 0, init_messages.msgs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MIN_NODE_LINE 50 /* IP: 7 + port: 5 + key: 38 + spaces: 2 = 70. ! (& e.g. tox.im = 6) */
|
#define MIN_NODE_LINE 50 /* IP: 7 + port: 5 + key: 38 + spaces: 2 = 70. ! (& e.g. tox.chat = 8) */
|
||||||
#define MAX_NODE_LINE 256 /* Approx max number of chars in a sever line (name + port + key) */
|
#define MAX_NODE_LINE 256 /* Approx max number of chars in a sever line (name + port + key) */
|
||||||
#define MAXNODES 50
|
#define MAXNODES 50
|
||||||
#define NODELEN (MAX_NODE_LINE - TOX_PUBLIC_KEY_SIZE - 7)
|
#define NODELEN (MAX_NODE_LINE - TOX_PUBLIC_KEY_SIZE - 7)
|
||||||
@ -381,6 +382,17 @@ int init_connection(Tox *m)
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void load_groups(Tox *m)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t numgroups = tox_group_get_number_groups(m);
|
||||||
|
|
||||||
|
for (i = 0; i < numgroups; ++i) {
|
||||||
|
if (init_groupchat_win(m, i, NULL, 0) == -1)
|
||||||
|
tox_group_leave(m, i, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void load_friendlist(Tox *m)
|
static void load_friendlist(Tox *m)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -551,15 +563,26 @@ static void init_tox_callbacks(Tox *m)
|
|||||||
tox_callback_friend_status(m, on_statuschange, NULL);
|
tox_callback_friend_status(m, on_statuschange, NULL);
|
||||||
tox_callback_friend_status_message(m, on_statusmessagechange, NULL);
|
tox_callback_friend_status_message(m, on_statusmessagechange, NULL);
|
||||||
tox_callback_friend_read_receipt(m, on_read_receipt, NULL);
|
tox_callback_friend_read_receipt(m, on_read_receipt, NULL);
|
||||||
tox_callback_group_invite(m, on_groupinvite, NULL);
|
|
||||||
tox_callback_group_message(m, on_groupmessage, NULL);
|
|
||||||
tox_callback_group_action(m, on_groupaction, NULL);
|
|
||||||
tox_callback_group_namelist_change(m, on_group_namelistchange, NULL);
|
|
||||||
tox_callback_group_title(m, on_group_titlechange, NULL);
|
|
||||||
tox_callback_file_recv(m, on_file_recv, NULL);
|
tox_callback_file_recv(m, on_file_recv, NULL);
|
||||||
tox_callback_file_chunk_request(m, on_file_chunk_request, NULL);
|
tox_callback_file_chunk_request(m, on_file_chunk_request, NULL);
|
||||||
tox_callback_file_recv_control(m, on_file_control, NULL);
|
tox_callback_file_recv_control(m, on_file_control, NULL);
|
||||||
tox_callback_file_recv_chunk(m, on_file_recv_chunk, NULL);
|
tox_callback_file_recv_chunk(m, on_file_recv_chunk, NULL);
|
||||||
|
tox_callback_group_invite(m, on_group_invite, NULL);
|
||||||
|
tox_callback_group_message(m, on_group_message, NULL);
|
||||||
|
tox_callback_group_private_message(m, on_group_private_message, NULL);
|
||||||
|
tox_callback_group_peerlist_update(m, on_group_namelistchange, NULL);
|
||||||
|
tox_callback_group_peer_join(m, on_group_peer_join, NULL);
|
||||||
|
tox_callback_group_peer_exit(m, on_group_peer_exit, NULL);
|
||||||
|
tox_callback_group_peer_name(m, on_group_nick_change, NULL);
|
||||||
|
tox_callback_group_topic(m, on_group_topic_change, NULL);
|
||||||
|
|
||||||
|
// tox_callback_group_peer_limit(m, on_group_peer_limit, NULL);
|
||||||
|
// tox_callback_group_privacy_state(m, on_group_privacy_state, NULL);
|
||||||
|
// tox_callback_group_password(m, on_group_password, NULL);
|
||||||
|
|
||||||
|
tox_callback_group_self_join(m, on_group_self_join, NULL);
|
||||||
|
tox_callback_group_join_fail(m, on_group_rejected, NULL);
|
||||||
|
tox_callback_group_moderation(m, on_group_moderation, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_tox_options(struct Tox_Options *tox_opts)
|
static void init_tox_options(struct Tox_Options *tox_opts)
|
||||||
@ -1171,6 +1194,7 @@ int main(int argc, char *argv[])
|
|||||||
if (init_mplex_away_timer(m) == -1)
|
if (init_mplex_away_timer(m) == -1)
|
||||||
queue_init_message("Failed to init mplex auto-away.");
|
queue_init_message("Failed to init mplex auto-away.");
|
||||||
|
|
||||||
|
load_groups(m);
|
||||||
print_init_messages(prompt);
|
print_init_messages(prompt);
|
||||||
cleanup_init_messages();
|
cleanup_init_messages();
|
||||||
|
|
||||||
|
18
src/toxic.h
18
src/toxic.h
@ -107,11 +107,6 @@ void on_nickchange(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t
|
|||||||
void on_statuschange(Tox *m, uint32_t friendnumber, TOX_USER_STATUS status, void *userdata);
|
void on_statuschange(Tox *m, uint32_t friendnumber, TOX_USER_STATUS status, void *userdata);
|
||||||
void on_statusmessagechange(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata);
|
void on_statusmessagechange(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata);
|
||||||
void on_friendadded(Tox *m, uint32_t friendnumber, bool sort);
|
void on_friendadded(Tox *m, uint32_t friendnumber, bool sort);
|
||||||
void on_groupmessage(Tox *m, int groupnumber, int peernumber, const uint8_t *message, uint16_t length, void *userdata);
|
|
||||||
void on_groupaction(Tox *m, int groupnumber, int peernumber, const uint8_t *action, uint16_t length, void *userdata);
|
|
||||||
void on_groupinvite(Tox *m, int32_t friendnumber, uint8_t type, const uint8_t *group_pub_key, uint16_t length, void *userdata);
|
|
||||||
void on_group_namelistchange(Tox *m, int groupnumber, int peernumber, uint8_t change, void *userdata);
|
|
||||||
void on_group_titlechange(Tox *m, int groupnumber, int peernumber, const uint8_t *title, uint8_t length, void *userdata);
|
|
||||||
void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position, size_t length, void *userdata);
|
void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position, size_t length, void *userdata);
|
||||||
void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data,
|
void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data,
|
||||||
size_t length, void *userdata);
|
size_t length, void *userdata);
|
||||||
@ -120,5 +115,18 @@ void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t k
|
|||||||
const uint8_t *filename, size_t filename_length, void *userdata);
|
const uint8_t *filename, size_t filename_length, void *userdata);
|
||||||
void on_typing_change(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata);
|
void on_typing_change(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata);
|
||||||
void on_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata);
|
void on_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata);
|
||||||
|
void on_group_invite(Tox *m, int32_t friendnumber, const uint8_t *invite_data, size_t length, void *userdata);
|
||||||
|
void on_group_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_MESSAGE_TYPE type,
|
||||||
|
const uint8_t *message, size_t length, void *userdata);
|
||||||
|
void on_group_private_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *message, size_t length, void *userdata);
|
||||||
|
void on_group_namelistchange(Tox *m, uint32_t groupnumber, void *userdata);
|
||||||
|
void on_group_peer_join(Tox *m, uint32_t groupnumber, uint32_t peernumber, void *userdata);
|
||||||
|
void on_group_peer_exit(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *partmsg, size_t length, void *userdata);
|
||||||
|
void on_group_topic_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *topic, size_t length, void *userdata);
|
||||||
|
void on_group_nick_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *newname, size_t length, void *userdata);
|
||||||
|
void on_group_self_join(Tox *m, uint32_t groupnumber, void *userdata);
|
||||||
|
void on_group_rejected(Tox *m, uint32_t groupnumber, TOX_GROUP_JOIN_FAIL type, void *userdata);
|
||||||
|
void on_group_moderation(Tox *m, uint32_t groupnumber, uint32_t source_peernum, uint32_t target_peernum,
|
||||||
|
TOX_GROUP_MOD_EVENT type, void *userdata);
|
||||||
|
|
||||||
#endif /* #define TOXIC_H */
|
#endif /* #define TOXIC_H */
|
||||||
|
131
src/windows.c
131
src/windows.c
@ -151,8 +151,18 @@ void on_friendadded(Tox *m, uint32_t friendnumber, bool sort)
|
|||||||
store_data(m, DATA_FILE);
|
store_data(m, DATA_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_groupmessage(Tox *m, int groupnumber, int peernumber, const uint8_t *message, uint16_t length,
|
void on_group_invite(Tox *m, int32_t friendnumber, const uint8_t *invite_data, size_t length, void *userdata)
|
||||||
void *userdata)
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
|
if (windows[i].onGroupInvite != NULL)
|
||||||
|
windows[i].onGroupInvite(&windows[i], m, friendnumber, (char *) invite_data, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_group_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_MESSAGE_TYPE type,
|
||||||
|
const uint8_t *message, size_t length, void *userdata)
|
||||||
{
|
{
|
||||||
char msg[MAX_STR_SIZE + 1];
|
char msg[MAX_STR_SIZE + 1];
|
||||||
length = copy_tox_str(msg, sizeof(msg), (const char *) message, length);
|
length = copy_tox_str(msg, sizeof(msg), (const char *) message, length);
|
||||||
@ -161,56 +171,121 @@ void on_groupmessage(Tox *m, int groupnumber, int peernumber, const uint8_t *mes
|
|||||||
|
|
||||||
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
if (windows[i].onGroupMessage != NULL)
|
if (windows[i].onGroupMessage != NULL)
|
||||||
windows[i].onGroupMessage(&windows[i], m, groupnumber, peernumber, msg, length);
|
windows[i].onGroupMessage(&windows[i], m, groupnumber, peernumber, type, msg, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_groupaction(Tox *m, int groupnumber, int peernumber, const uint8_t *action, uint16_t length,
|
void on_group_private_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *message,
|
||||||
void *userdata)
|
size_t length, void *userdata)
|
||||||
{
|
{
|
||||||
char msg[MAX_STR_SIZE + 1];
|
char msg[MAX_STR_SIZE + 1];
|
||||||
length = copy_tox_str(msg, sizeof(msg), (const char *) action, length);
|
length = copy_tox_str(msg, sizeof(msg), (const char *) message, length);
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
if (windows[i].onGroupAction != NULL)
|
if (windows[i].onGroupPrivateMessage != NULL)
|
||||||
windows[i].onGroupAction(&windows[i], m, groupnumber, peernumber, msg, length);
|
windows[i].onGroupPrivateMessage(&windows[i], m, groupnumber, peernumber, msg, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_groupinvite(Tox *m, int32_t friendnumber, uint8_t type, const uint8_t *group_pub_key, uint16_t length,
|
void on_group_namelistchange(Tox *m, uint32_t groupnumber, void *userdata)
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
|
||||||
if (windows[i].onGroupInvite != NULL)
|
|
||||||
windows[i].onGroupInvite(&windows[i], m, friendnumber, type, (char *) group_pub_key, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_group_namelistchange(Tox *m, int groupnumber, int peernumber, uint8_t change, void *userdata)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
if (windows[i].onGroupNamelistChange != NULL)
|
if (windows[i].onGroupNamelistChange != NULL)
|
||||||
windows[i].onGroupNamelistChange(&windows[i], m, groupnumber, peernumber, change);
|
windows[i].onGroupNamelistChange(&windows[i], m, groupnumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_group_titlechange(Tox *m, int groupnumber, int peernumber, const uint8_t *title, uint8_t length,
|
void on_group_peer_join(Tox *m, uint32_t groupnumber, uint32_t peernumber, void *userdata)
|
||||||
void *userdata)
|
|
||||||
{
|
{
|
||||||
char data[MAX_STR_SIZE + 1];
|
size_t i;
|
||||||
length = copy_tox_str(data, sizeof(data), (const char *) title, length);
|
|
||||||
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
|
if (windows[i].onGroupPeerJoin != NULL)
|
||||||
|
windows[i].onGroupPeerJoin(&windows[i], m, groupnumber, peernumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_group_peer_exit(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *partmsg, size_t length,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
char msg[MAX_STR_SIZE + 1];
|
||||||
|
|
||||||
|
if (length == 0 || !partmsg) {
|
||||||
|
strcpy(msg, "Quit");
|
||||||
|
length = strlen(msg);
|
||||||
|
} else {
|
||||||
|
length = copy_tox_str(msg, sizeof(msg), (const char *) partmsg, length);
|
||||||
|
}
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
if (windows[i].onGroupTitleChange != NULL)
|
if (windows[i].onGroupPeerExit != NULL)
|
||||||
windows[i].onGroupTitleChange(&windows[i], m, groupnumber, peernumber, data, length);
|
windows[i].onGroupPeerExit(&windows[i], m, groupnumber, peernumber, msg, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_group_topic_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *topic, size_t length,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
char data[MAX_STR_SIZE + 1];
|
||||||
|
length = copy_tox_str(data, sizeof(data), (const char *) topic, length);
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
|
if (windows[i].onGroupTopicChange != NULL)
|
||||||
|
windows[i].onGroupTopicChange(&windows[i], m, groupnumber, peernumber, data, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_group_nick_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *newname, size_t length,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
char name[TOXIC_MAX_NAME_LENGTH + 1];
|
||||||
|
length = copy_tox_str(name, sizeof(name), (const char *) newname, length);
|
||||||
|
filter_str(name, length);
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
|
if (windows[i].onGroupNickChange != NULL)
|
||||||
|
windows[i].onGroupNickChange(&windows[i], m, groupnumber, peernumber, name, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_group_self_join(Tox *m, uint32_t groupnumber, void *userdata)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
|
if (windows[i].onGroupSelfJoin != NULL)
|
||||||
|
windows[i].onGroupSelfJoin(&windows[i], m, groupnumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_group_rejected(Tox *m, uint32_t groupnumber, TOX_GROUP_JOIN_FAIL type, void *userdata)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
|
if (windows[i].onGroupRejected != NULL)
|
||||||
|
windows[i].onGroupRejected(&windows[i], m, groupnumber, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_group_moderation(Tox *m, uint32_t groupnumber, uint32_t source_peernum, uint32_t target_peernum,
|
||||||
|
TOX_GROUP_MOD_EVENT type, void *userdata)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
|
if (windows[i].onGroupModeration != NULL)
|
||||||
|
windows[i].onGroupModeration(&windows[i], m, groupnumber, source_peernum, target_peernum, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +670,7 @@ void kill_all_windows(Tox *m)
|
|||||||
if (windows[i].is_chat)
|
if (windows[i].is_chat)
|
||||||
kill_chat_window(&windows[i], m);
|
kill_chat_window(&windows[i], m);
|
||||||
else if (windows[i].is_groupchat)
|
else if (windows[i].is_groupchat)
|
||||||
close_groupchat(&windows[i], m, i);
|
close_groupchat(&windows[i], m, windows[i].num);
|
||||||
}
|
}
|
||||||
|
|
||||||
kill_prompt_window(prompt);
|
kill_prompt_window(prompt);
|
||||||
|
@ -121,11 +121,6 @@ struct ToxWindow {
|
|||||||
void(*onNickChange)(ToxWindow *, Tox *, uint32_t, const char *, size_t);
|
void(*onNickChange)(ToxWindow *, Tox *, uint32_t, const char *, size_t);
|
||||||
void(*onStatusChange)(ToxWindow *, Tox *, uint32_t, TOX_USER_STATUS);
|
void(*onStatusChange)(ToxWindow *, Tox *, uint32_t, TOX_USER_STATUS);
|
||||||
void(*onStatusMessageChange)(ToxWindow *, uint32_t, const char *, size_t);
|
void(*onStatusMessageChange)(ToxWindow *, uint32_t, const char *, size_t);
|
||||||
void(*onGroupMessage)(ToxWindow *, Tox *, int, int, const char *, uint16_t);
|
|
||||||
void(*onGroupAction)(ToxWindow *, Tox *, int, int, const char *, uint16_t);
|
|
||||||
void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, uint8_t, const char *, uint16_t);
|
|
||||||
void(*onGroupNamelistChange)(ToxWindow *, Tox *, int, int, uint8_t);
|
|
||||||
void(*onGroupTitleChange)(ToxWindow *, Tox *, int, int, const char *, uint8_t);
|
|
||||||
void(*onFileChunkRequest)(ToxWindow *, Tox *, uint32_t, uint32_t, uint64_t, size_t);
|
void(*onFileChunkRequest)(ToxWindow *, Tox *, uint32_t, uint32_t, uint64_t, size_t);
|
||||||
void(*onFileRecvChunk)(ToxWindow *, Tox *, uint32_t, uint32_t, uint64_t, const char *, size_t);
|
void(*onFileRecvChunk)(ToxWindow *, Tox *, uint32_t, uint32_t, uint64_t, const char *, size_t);
|
||||||
void(*onFileControl)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_FILE_CONTROL);
|
void(*onFileControl)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_FILE_CONTROL);
|
||||||
@ -133,6 +128,18 @@ struct ToxWindow {
|
|||||||
void(*onTypingChange)(ToxWindow *, Tox *, uint32_t, bool);
|
void(*onTypingChange)(ToxWindow *, Tox *, uint32_t, bool);
|
||||||
void(*onReadReceipt)(ToxWindow *, Tox *, uint32_t, uint32_t);
|
void(*onReadReceipt)(ToxWindow *, Tox *, uint32_t, uint32_t);
|
||||||
|
|
||||||
|
void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, const char *, size_t);
|
||||||
|
void(*onGroupMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_MESSAGE_TYPE, const char *, size_t);
|
||||||
|
void(*onGroupPrivateMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
|
||||||
|
void(*onGroupNamelistChange)(ToxWindow *, Tox *, uint32_t);
|
||||||
|
void(*onGroupPeerJoin)(ToxWindow *, Tox *, uint32_t, uint32_t);
|
||||||
|
void(*onGroupPeerExit)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
|
||||||
|
void(*onGroupNickChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
|
||||||
|
void(*onGroupTopicChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
|
||||||
|
void(*onGroupSelfJoin)(ToxWindow *, Tox *, uint32_t);
|
||||||
|
void(*onGroupRejected)(ToxWindow *, Tox *, uint32_t, TOX_GROUP_JOIN_FAIL);
|
||||||
|
void(*onGroupModeration)(ToxWindow *, Tox *, uint32_t, uint32_t, uint32_t, TOX_GROUP_MOD_EVENT);
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
|
|
||||||
void(*onInvite)(ToxWindow *, ToxAv *, int);
|
void(*onInvite)(ToxWindow *, ToxAv *, int);
|
||||||
@ -146,7 +153,6 @@ struct ToxWindow {
|
|||||||
void(*onEnd)(ToxWindow *, ToxAv *, int);
|
void(*onEnd)(ToxWindow *, ToxAv *, int);
|
||||||
void(*onRequestTimeout)(ToxWindow *, ToxAv *, int);
|
void(*onRequestTimeout)(ToxWindow *, ToxAv *, int);
|
||||||
void(*onPeerTimeout)(ToxWindow *, ToxAv *, int);
|
void(*onPeerTimeout)(ToxWindow *, ToxAv *, int);
|
||||||
void(*onWriteDevice)(ToxWindow *, Tox *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int);
|
|
||||||
|
|
||||||
int call_idx; /* If in a call will have this index set, otherwise it's -1.
|
int call_idx; /* If in a call will have this index set, otherwise it's -1.
|
||||||
* Don't modify outside av callbacks. */
|
* Don't modify outside av callbacks. */
|
||||||
|
Loading…
Reference in New Issue
Block a user