1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-22 21:43:02 +01:00

message sending queue for fake offline messaging

This commit is contained in:
Jfreegman 2014-09-06 13:18:42 -04:00
parent 6876df4a45
commit 3c2c1f15ce
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
11 changed files with 185 additions and 29 deletions

View File

@ -13,7 +13,7 @@ LDFLAGS = $(USER_LDFLAGS)
OBJ = chat.o chat_commands.o configdir.o dns.o execute.o file_senders.o notify.o OBJ = chat.o chat_commands.o configdir.o dns.o execute.o file_senders.o notify.o
OBJ += friendlist.o global_commands.o groupchat.o line_info.o input.o help.o autocomplete.o OBJ += friendlist.o global_commands.o groupchat.o line_info.o input.o help.o autocomplete.o
OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o message_queue.o
# Check on wich system we are running # Check on wich system we are running
UNAME_S = $(shell uname -s) UNAME_S = $(shell uname -s)

View File

@ -43,6 +43,7 @@
#include "help.h" #include "help.h"
#include "autocomplete.h" #include "autocomplete.h"
#include "notify.h" #include "notify.h"
#include "message_queue.h"
#ifdef _AUDIO #ifdef _AUDIO
#include "audio_call.h" #include "audio_call.h"
@ -134,6 +135,7 @@ void kill_chat_window(ToxWindow *self, Tox *m)
close_all_file_receivers(m, self->num); close_all_file_receivers(m, self->num);
log_disable(ctx->log); log_disable(ctx->log);
line_info_cleanup(ctx->hst); line_info_cleanup(ctx->hst);
cqueue_cleanup(ctx->cqueue);
#ifdef _AUDIO #ifdef _AUDIO
stop_current_call(self); stop_current_call(self);
@ -144,7 +146,6 @@ void kill_chat_window(ToxWindow *self, Tox *m)
delwin(statusbar->topline); delwin(statusbar->topline);
free(ctx->log); free(ctx->log);
free(ctx->hst);
free(ctx); free(ctx);
free(self->help); free(self->help);
free(statusbar); free(statusbar);
@ -293,8 +294,6 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
if (self->num != num) if (self->num != num)
return; return;
const char *errmsg;
/* holds the filename appended to the user specified path */ /* holds the filename appended to the user specified path */
char filename_path[MAX_STR_SIZE] = {0}; char filename_path[MAX_STR_SIZE] = {0};
@ -308,8 +307,7 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
filename_nopath, sizestr); filename_nopath, sizestr);
if (filenum >= MAX_FILES) { if (filenum >= MAX_FILES) {
errmsg = "Too many pending file requests; discarding."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Too many pending file requests; discarding.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
return; return;
} }
@ -320,8 +318,7 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
} }
if (len >= sizeof(Friends.list[num].file_receiver[filenum].filename)) { if (len >= sizeof(Friends.list[num].file_receiver[filenum].filename)) {
errmsg = "File name too long; discarding."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File name too long; discarding.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
return; return;
} }
@ -351,8 +348,7 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
filename[len + d_len] = '\0'; filename[len + d_len] = '\0';
if (count > 999) { if (count > 999) {
errmsg = "Error saving file to disk."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error saving file to disk.");
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
return; return;
} }
} }
@ -494,7 +490,10 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t rec
case TOX_FILECONTROL_FINISHED: case TOX_FILECONTROL_FINISHED:
if (receive_send == 0) { if (receive_send == 0) {
print_progress_bar(self, filenum, num, 100.0); print_progress_bar(self, filenum, num, 100.0);
snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename);
char filename_nopath[MAX_STR_SIZE];
get_file_name(filename_nopath, sizeof(filename_nopath), filename);
snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename_nopath);
chat_close_file_receiver(m, filenum, num, TOX_FILECONTROL_FINISHED); chat_close_file_receiver(m, filenum, num, TOX_FILECONTROL_FINISHED);
} else { } else {
snprintf(msg, sizeof(msg), "File '%s' successfuly sent.", filename); snprintf(msg, sizeof(msg), "File '%s' successfuly sent.", filename);
@ -833,12 +832,8 @@ static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action)
get_time_str(timefrmt, sizeof(timefrmt)); get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, selfname, NULL, ACTION, 0, 0, "%s", action); line_info_add(self, timefrmt, selfname, NULL, ACTION, 0, 0, "%s", action);
write_to_log(action, selfname, ctx->log, true);
if (tox_send_action(m, self->num, (uint8_t *) action, strlen(action)) == 0) { cqueue_add(ctx->cqueue, action, strlen(action), QACTION, ctx->hst->line_end->id);
line_info_add(self, NULL, selfname, NULL, SYS_MSG, 0, RED, " * Failed to send action.");
} else {
write_to_log(action, selfname, ctx->log, true);
}
} }
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
@ -919,12 +914,8 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
get_time_str(timefrmt, sizeof(timefrmt)); get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, selfname, NULL, OUT_MSG, 0, 0, "%s", line); line_info_add(self, timefrmt, selfname, NULL, OUT_MSG, 0, 0, "%s", line);
write_to_log(line, selfname, ctx->log, false);
if (!statusbar->is_online || tox_send_message(m, self->num, (uint8_t *) line, strlen(line)) == 0) { cqueue_add(ctx->cqueue, line, strlen(line), QMESSAGE, ctx->hst->line_end->id);
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to send message.");
} else {
write_to_log(line, selfname, ctx->log, false);
}
} }
wclear(ctx->linewin); wclear(ctx->linewin);
@ -1090,11 +1081,13 @@ static void chat_onInit(ToxWindow *self, Tox *m)
ctx->hst = calloc(1, sizeof(struct history)); ctx->hst = calloc(1, sizeof(struct history));
ctx->log = calloc(1, sizeof(struct chatlog)); ctx->log = calloc(1, sizeof(struct chatlog));
ctx->cqueue = calloc(1, sizeof(struct chat_queue));
if (ctx->log == NULL || ctx->hst == NULL) if (ctx->log == NULL || ctx->hst == NULL || ctx->cqueue == NULL)
exit_toxic_err("failed in chat_onInit", FATALERR_MEMORY); exit_toxic_err("failed in chat_onInit", FATALERR_MEMORY);
line_info_init(ctx->hst); line_info_init(ctx->hst);
ctx->cqueue->friendnum = self->num;
if (Friends.list[self->num].logging_on) if (Friends.list[self->num].logging_on)
log_enable(nick, Friends.list[self->num].pub_key, ctx->log); log_enable(nick, Friends.list[self->num].pub_key, ctx->log);

View File

@ -276,6 +276,7 @@ void do_file_senders(Tox *m)
box_notify2(self, error, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", msg); box_notify2(self, error, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", msg);
else else
box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", msg); box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", msg);
continue; continue;
} }

View File

@ -97,7 +97,6 @@ void kill_groupchat_window(ToxWindow *self)
delwin(ctx->history); delwin(ctx->history);
delwin(ctx->sidebar); delwin(ctx->sidebar);
free(ctx->log); free(ctx->log);
free(ctx->hst);
free(ctx); free(ctx);
free(self->help); free(self->help);
del_window(self); del_window(self);

View File

@ -89,6 +89,8 @@ void line_info_cleanup(struct history *hst)
if (hst->queue[i]) if (hst->queue[i])
free(hst->queue[i]); free(hst->queue[i]);
} }
free(hst);
} }
/* moves root forward and frees previous root */ /* moves root forward and frees previous root */

87
src/message_queue.c Normal file
View File

@ -0,0 +1,87 @@
/* message_queue.c
*
*
* Copyright (C) 2014 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Toxic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdlib.h>
#include "toxic.h"
#include "windows.h"
#include "message_queue.h"
void cqueue_cleanup(struct chat_queue *q)
{
struct cqueue_msg *tmp1 = q->root;
while (tmp1) {
struct cqueue_msg *tmp2 = tmp1->next;
free(tmp1);
tmp1 = tmp2;
}
free(q);
}
void cqueue_add(struct chat_queue *q, const char *msg, int len, uint8_t type, uint32_t line_id)
{
struct cqueue_msg *new_m = malloc(sizeof(struct cqueue_msg));
if (new_m == NULL)
exit_toxic_err("failed in cqueue_message", FATALERR_MEMORY);
snprintf(new_m->message, sizeof(new_m->message), "%s", msg);
new_m->len = len;
new_m->type = type;
new_m->line_id = line_id;
new_m->next = NULL;
if (q->root == NULL)
q->root = new_m;
else
q->end->next = new_m;
q->end = new_m;
}
static void cqueue_remove(struct chat_queue *q)
{
struct cqueue_msg *new_root = q->root->next;
free(q->root);
q->root = new_root;
}
void cqueue_try_send(Tox *m, struct chat_queue *q)
{
if (q->root == NULL)
return;
struct cqueue_msg *q_msg = q->root;
uint32_t receipt;
if (q_msg->type == QMESSAGE)
receipt = tox_send_message(m, q->friendnum, (uint8_t *) q_msg->message, q_msg->len);
else
receipt = tox_send_action(m, q->friendnum, (uint8_t *) q_msg->message, q_msg->len);
if (receipt == 0)
return;
cqueue_remove(q);
}

46
src/message_queue.h Normal file
View File

@ -0,0 +1,46 @@
/* message_queue.h
*
*
* Copyright (C) 2014 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Toxic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
enum {
QMESSAGE,
QACTION,
} MESSAGE_TYPE;
struct cqueue_msg {
char message[MAX_STR_SIZE];
int len;
int line_id;
uint8_t type;
uint32_t receipt;
struct cqueue_msg *next;
};
struct chat_queue {
struct cqueue_msg *root;
struct cqueue_msg *end;
int friendnum;
};
void cqueue_cleanup(struct chat_queue *q);
void cqueue_add(struct chat_queue *q, const char *msg, int len, uint8_t type, uint32_t line_id);
void cqueue_check(Tox *m);
void cqueue_try_send(Tox *m, struct chat_queue *q);

View File

@ -166,7 +166,7 @@ bool is_playing(int source)
return ready == AL_PLAYING; return ready == AL_PLAYING;
} }
/* Terminate all sounds but wait them to finish first */ /* Terminate all sounds but wait for them to finish first */
void graceful_clear() void graceful_clear()
{ {
int i; int i;
@ -192,7 +192,6 @@ void graceful_clear()
else break; else break;
} }
} }
} }
if (i == ACTIVE_NOTIFS_MAX) { if (i == ACTIVE_NOTIFS_MAX) {

View File

@ -88,7 +88,6 @@ void kill_prompt_window(ToxWindow *self)
delwin(statusbar->topline); delwin(statusbar->topline);
free(ctx->log); free(ctx->log);
free(ctx->hst);
free(ctx); free(ctx);
free(self->help); free(self->help);
free(statusbar); free(statusbar);

View File

@ -53,6 +53,7 @@
#include "log.h" #include "log.h"
#include "notify.h" #include "notify.h"
#include "device.h" #include "device.h"
#include "message_queue.h"
#ifdef _AUDIO #ifdef _AUDIO
#include "audio_call.h" #include "audio_call.h"
@ -74,6 +75,7 @@ ToxWindow *prompt = NULL;
#define AUTOSAVE_FREQ 60 #define AUTOSAVE_FREQ 60
struct _Winthread Winthread; struct _Winthread Winthread;
struct _cqueue_thread cqueue_thread;
struct arg_opts arg_opts; struct arg_opts arg_opts;
struct user_settings *user_settings_ = NULL; struct user_settings *user_settings_ = NULL;
@ -573,6 +575,26 @@ void *thread_winref(void *data)
} }
} }
void *thread_cqueue(void *data)
{
Tox *m = (Tox *) data;
while (true) {
pthread_mutex_lock(&Winthread.lock);
int i;
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
ToxWindow *toxwin = get_window_ptr(i);
if (toxwin != NULL && toxwin->is_chat && tox_get_friend_connection_status(m, toxwin->num) == 1)
cqueue_try_send(m, toxwin->chatwin->cqueue);
}
pthread_mutex_unlock(&Winthread.lock);
usleep(100000); /* 0.1 second */
}
}
static void print_usage(void) static void print_usage(void)
{ {
fprintf(stderr, "usage: toxic [OPTION] [FILE ...]\n"); fprintf(stderr, "usage: toxic [OPTION] [FILE ...]\n");
@ -811,11 +833,14 @@ int main(int argc, char *argv[])
if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0) if (pthread_create(&Winthread.tid, NULL, thread_winref, (void *) m) != 0)
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE); exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
/* thread for message queue */
if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0)
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
#ifdef _AUDIO #ifdef _AUDIO
av = init_audio(prompt, m); av = init_audio(prompt, m);
set_primary_device(input, user_settings_->audio_in_dev); set_primary_device(input, user_settings_->audio_in_dev);
set_primary_device(output, user_settings_->audio_out_dev); set_primary_device(output, user_settings_->audio_out_dev);

View File

@ -71,6 +71,10 @@ struct _Winthread {
bool flag_resize; bool flag_resize;
}; };
struct _cqueue_thread {
pthread_t tid;
};
struct arg_opts { struct arg_opts {
int ignore_data_file; int ignore_data_file;
int use_ipv4; int use_ipv4;
@ -208,6 +212,7 @@ struct ChatContext {
struct history *hst; struct history *hst;
struct chatlog *log; struct chatlog *log;
struct chat_queue *cqueue;
#ifdef _AUDIO #ifdef _AUDIO
struct infobox infobox; struct infobox infobox;