mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-23 02:13:01 +01:00
allow resuming of broken file transfers (needs testing)
This commit is contained in:
parent
ae83725cb6
commit
b870679f2c
59
src/chat.c
59
src/chat.c
@ -176,6 +176,9 @@ static void chat_onMessage(ToxWindow *self, Tox *m, int32_t num, const char *msg
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void chat_resume_file_transfers(Tox *m, int fnum);
|
||||||
|
static void chat_stop_file_senders(int fnum);
|
||||||
|
|
||||||
static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status)
|
static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status)
|
||||||
{
|
{
|
||||||
if (self->num != num)
|
if (self->num != num)
|
||||||
@ -187,13 +190,15 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_
|
|||||||
statusbar->is_online = true;
|
statusbar->is_online = true;
|
||||||
Friends.list[num].is_typing = user_settings_->show_typing_other == SHOW_TYPING_ON
|
Friends.list[num].is_typing = user_settings_->show_typing_other == SHOW_TYPING_ON
|
||||||
? tox_get_is_typing(m, num) : 0;
|
? tox_get_is_typing(m, num) : 0;
|
||||||
|
chat_resume_file_transfers(m, num);
|
||||||
} else { /* Friend goes offline */
|
} else { /* Friend goes offline */
|
||||||
statusbar->is_online = false;
|
statusbar->is_online = false;
|
||||||
Friends.list[num].is_typing = 0;
|
Friends.list[num].is_typing = 0;
|
||||||
|
|
||||||
if (self->chatwin->self_is_typing)
|
if (self->chatwin->self_is_typing)
|
||||||
set_self_typingstatus(self, m, 0);
|
set_self_typingstatus(self, m, 0);
|
||||||
|
|
||||||
|
chat_stop_file_senders(num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,6 +355,36 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
|
|||||||
"Incoming file: %s", filename );
|
"Incoming file: %s", filename );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stops active file senders for this friend. Call when a friend goes offline */
|
||||||
|
static void chat_stop_file_senders(int fnum)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_FILES; ++i) {
|
||||||
|
if (file_senders[i].active && file_senders[i].friendnum == fnum)
|
||||||
|
file_senders[i].noconnection = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tries to resume broken file transfers. Call when a friend comes online */
|
||||||
|
static void chat_resume_file_transfers(Tox *m, int fnum)
|
||||||
|
{
|
||||||
|
if (Friends.list[fnum].active_file_receivers == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_FILES; ++i) {
|
||||||
|
if (Friends.list[fnum].file_receiver[i].active && !Friends.list[fnum].file_receiver[i].paused) {
|
||||||
|
uint8_t bytes_recv[sizeof(uint64_t)];
|
||||||
|
memcpy(bytes_recv, &Friends.list[fnum].file_receiver[i].bytes_recv, sizeof(uint64_t));
|
||||||
|
net_to_host(bytes_recv, sizeof(uint64_t));
|
||||||
|
int filenum = Friends.list[fnum].file_receiver[i].filenum;
|
||||||
|
tox_file_send_control(m, fnum, 1, filenum, TOX_FILECONTROL_RESUME_BROKEN, bytes_recv, sizeof(uint64_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* set CTRL to -1 if we don't want to send a control signal.
|
/* set CTRL to -1 if we don't want to send a control signal.
|
||||||
set msg to NULL if we don't want to display a message */
|
set msg to NULL if we don't want to display a message */
|
||||||
void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL)
|
void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL)
|
||||||
@ -363,6 +398,7 @@ void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL)
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
memset(&Friends.list[friendnum].file_receiver[filenum], 0, sizeof(struct FileReceiver));
|
memset(&Friends.list[friendnum].file_receiver[filenum], 0, sizeof(struct FileReceiver));
|
||||||
|
--Friends.list[friendnum].active_file_receivers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_all_file_receivers(Tox *m, int friendnum)
|
static void close_all_file_receivers(Tox *m, int friendnum)
|
||||||
@ -453,6 +489,26 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t rec
|
|||||||
self->name, "%s", msg);
|
self->name, "%s", msg);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOX_FILECONTROL_RESUME_BROKEN:
|
||||||
|
if (receive_send == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
FILE *fp = file_senders[i].file;
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
uint8_t tmp[sizeof(uint64_t)];
|
||||||
|
memcpy(tmp, &data, sizeof(uint64_t));
|
||||||
|
net_to_host(tmp, sizeof(uint64_t));
|
||||||
|
uint64_t datapos;
|
||||||
|
memcpy(&datapos, tmp, sizeof(uint64_t));
|
||||||
|
|
||||||
|
fseek(fp, datapos, SEEK_SET);
|
||||||
|
tox_file_send_control(m, num, 0, filenum, TOX_FILECONTROL_ACCEPT, 0, 0);
|
||||||
|
file_senders[i].noconnection = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg[0])
|
if (msg[0])
|
||||||
@ -475,6 +531,7 @@ static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenu
|
|||||||
}
|
}
|
||||||
|
|
||||||
Friends.list[num].file_receiver[filenum].bps += length;
|
Friends.list[num].file_receiver[filenum].bps += length;
|
||||||
|
Friends.list[num].file_receiver[filenum].bytes_recv += length;
|
||||||
double remain = (double) tox_file_data_remaining(m, num, filenum, 1);
|
double remain = (double) tox_file_data_remaining(m, num, filenum, 1);
|
||||||
uint64_t curtime = get_unix_time();
|
uint64_t curtime = get_unix_time();
|
||||||
|
|
||||||
|
@ -177,13 +177,15 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
|||||||
if ((Friends.list[self->num].file_receiver[filenum].file = fopen(filename, "a")) == NULL) {
|
if ((Friends.list[self->num].file_receiver[filenum].file = fopen(filename, "a")) == NULL) {
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Error writing to file.");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Error writing to file.");
|
||||||
tox_file_send_control(m, self->num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0);
|
tox_file_send_control(m, self->num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0);
|
||||||
|
} else {
|
||||||
|
Friends.list[self->num].file_receiver[filenum].active = true;
|
||||||
|
++Friends.list[self->num].active_file_receivers;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed.");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File transfer failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Friends.list[self->num].file_receiver[filenum].pending = false;
|
Friends.list[self->num].file_receiver[filenum].pending = false;
|
||||||
Friends.list[self->num].file_receiver[filenum].active = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
@ -44,13 +44,14 @@
|
|||||||
|
|
||||||
#define DNS3_KEY_SIZE 32
|
#define DNS3_KEY_SIZE 32
|
||||||
#define MAX_DNS_REQST_SIZE 255
|
#define MAX_DNS_REQST_SIZE 255
|
||||||
#define NUM_DNS3_BACKUP_SERVERS 2 /* must correspond to number of items in dns3_servers array */
|
|
||||||
#define TOX_DNS3_TXT_PREFIX "v=tox3;id="
|
#define TOX_DNS3_TXT_PREFIX "v=tox3;id="
|
||||||
|
|
||||||
extern struct _Winthread Winthread;
|
extern struct _Winthread Winthread;
|
||||||
extern struct _dns3_servers dns3_servers;
|
extern struct _dns3_servers dns3_servers;
|
||||||
extern struct arg_opts arg_opts;
|
extern struct arg_opts arg_opts;
|
||||||
|
|
||||||
|
#define NUM_DNS3_BACKUP_SERVERS 2
|
||||||
|
|
||||||
/* Hardcoded backup in case domain list is not loaded */
|
/* Hardcoded backup in case domain list is not loaded */
|
||||||
static struct dns3_server_backup {
|
static struct dns3_server_backup {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -217,7 +217,9 @@ void do_file_senders(Tox *m)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file_senders[i].noconnection == false)
|
||||||
send_file_data(self, m, i, friendnum, filenum, filename);
|
send_file_data(self, m, i, friendnum, filenum, filename);
|
||||||
|
|
||||||
file_senders[i].queue_pos = num_active_file_senders - 1;
|
file_senders[i].queue_pos = num_active_file_senders - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ typedef struct {
|
|||||||
ToxWindow *toxwin;
|
ToxWindow *toxwin;
|
||||||
int32_t friendnum;
|
int32_t friendnum;
|
||||||
bool active;
|
bool active;
|
||||||
|
bool noconnection;
|
||||||
bool finished;
|
bool finished;
|
||||||
int filenum;
|
int filenum;
|
||||||
char nextpiece[FILE_PIECE_SIZE];
|
char nextpiece[FILE_PIECE_SIZE];
|
||||||
|
@ -35,9 +35,11 @@ struct FileReceiver {
|
|||||||
FILE *file;
|
FILE *file;
|
||||||
bool pending;
|
bool pending;
|
||||||
bool active;
|
bool active;
|
||||||
|
bool paused;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
uint64_t bytes_recv;
|
||||||
double bps;
|
double bps;
|
||||||
uint64_t last_progress;
|
uint64_t last_progress; /* unix-time when we last updated progress */
|
||||||
uint32_t line_id;
|
uint32_t line_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,6 +66,7 @@ typedef struct {
|
|||||||
uint8_t status;
|
uint8_t status;
|
||||||
struct LastOnline last_online;
|
struct LastOnline last_online;
|
||||||
struct FileReceiver file_receiver[MAX_FILES];
|
struct FileReceiver file_receiver[MAX_FILES];
|
||||||
|
uint8_t active_file_receivers;
|
||||||
} ToxicFriend;
|
} ToxicFriend;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user