mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'fixed-receipts' into new_api
This commit is contained in:
commit
af881e820a
|
@ -214,7 +214,6 @@ static int32_t init_new_friend(Messenger *m, const uint8_t *real_pk, uint8_t sta
|
|||
m->friendlist[i].avatar_send_data.last_reset = 0;
|
||||
m->friendlist[i].is_typing = 0;
|
||||
m->friendlist[i].message_id = 0;
|
||||
m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
|
||||
friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet,
|
||||
&handle_custom_lossy_packet, m, i);
|
||||
|
||||
|
@ -315,6 +314,75 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *real_pk)
|
|||
return init_new_friend(m, real_pk, FRIEND_CONFIRMED);
|
||||
}
|
||||
|
||||
static int clear_receipts(Messenger *m, int32_t friendnumber)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return -1;
|
||||
|
||||
struct Receipts *receipts = m->friendlist[friendnumber].receipts_start;
|
||||
|
||||
while (receipts) {
|
||||
struct Receipts *temp_r = receipts->next;
|
||||
free(receipts);
|
||||
receipts = temp_r;
|
||||
}
|
||||
|
||||
m->friendlist[friendnumber].receipts_start = NULL;
|
||||
m->friendlist[friendnumber].receipts_end = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_receipt(Messenger *m, int32_t friendnumber, uint32_t packet_num, uint32_t msg_id)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return -1;
|
||||
|
||||
struct Receipts *new = calloc(1, sizeof(struct Receipts));
|
||||
|
||||
if (!new)
|
||||
return -1;
|
||||
|
||||
new->packet_num = packet_num;
|
||||
new->msg_id = msg_id;
|
||||
|
||||
if (!m->friendlist[friendnumber].receipts_start) {
|
||||
m->friendlist[friendnumber].receipts_start = new;
|
||||
} else {
|
||||
m->friendlist[friendnumber].receipts_end->next = new;
|
||||
}
|
||||
|
||||
m->friendlist[friendnumber].receipts_end = new;
|
||||
new->next = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_receipts(Messenger *m, int32_t friendnumber)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return -1;
|
||||
|
||||
struct Receipts *receipts = m->friendlist[friendnumber].receipts_start;
|
||||
|
||||
while (receipts) {
|
||||
struct Receipts *temp_r = receipts->next;
|
||||
|
||||
if (cryptpacket_received(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, m->friendlist[friendnumber].friendcon_id), receipts->packet_num) == -1)
|
||||
break;
|
||||
|
||||
if (m->read_receipt)
|
||||
(*m->read_receipt)(m, friendnumber, receipts->msg_id, m->read_receipt_userdata);
|
||||
|
||||
free(receipts);
|
||||
m->friendlist[friendnumber].receipts_start = temp_r;
|
||||
receipts = temp_r;
|
||||
}
|
||||
|
||||
if (!m->friendlist[friendnumber].receipts_start)
|
||||
m->friendlist[friendnumber].receipts_end = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove a friend.
|
||||
*
|
||||
* return 0 if success.
|
||||
|
@ -329,6 +397,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
|
|||
remove_online_friend(m, friendnumber);
|
||||
|
||||
free(m->friendlist[friendnumber].avatar_recv_data);
|
||||
clear_receipts(m, friendnumber);
|
||||
remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk);
|
||||
friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0);
|
||||
kill_friend_connection(m->fr_c, m->friendlist[friendnumber].friendcon_id);
|
||||
|
@ -381,6 +450,37 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t send_message_generic(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length,
|
||||
uint8_t packet_id)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return 0;
|
||||
|
||||
if (length >= MAX_CRYPTO_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
|
||||
return 0;
|
||||
|
||||
uint8_t packet[length + 1];
|
||||
packet[0] = packet_id;
|
||||
|
||||
if (length != 0)
|
||||
memcpy(packet + 1, message, length);
|
||||
|
||||
int64_t packet_num = write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, m->friendlist[friendnumber].friendcon_id), packet, length + 1, 0);
|
||||
|
||||
if (packet_num == -1)
|
||||
return 0;
|
||||
|
||||
uint32_t msg_id = ++m->friendlist[friendnumber].message_id;
|
||||
|
||||
if (msg_id == 0) {
|
||||
msg_id = ++m->friendlist[friendnumber].message_id; // Otherwise, false error
|
||||
}
|
||||
|
||||
add_receipt(m, friendnumber, packet_num, msg_id);
|
||||
return msg_id;
|
||||
}
|
||||
|
||||
/* Send a text chat message to an online friend.
|
||||
*
|
||||
* return the message id if packet was successfully put into the send queue.
|
||||
|
@ -388,32 +488,7 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber)
|
|||
*/
|
||||
uint32_t m_sendmessage(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return 0;
|
||||
|
||||
uint32_t msgid = ++m->friendlist[friendnumber].message_id;
|
||||
|
||||
if (msgid == 0)
|
||||
msgid = 1; // Otherwise, false error
|
||||
|
||||
if (m_sendmessage_withid(m, friendnumber, msgid, message, length)) {
|
||||
return msgid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *message,
|
||||
uint32_t length)
|
||||
{
|
||||
if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)) || length == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t temp[sizeof(theid) + length];
|
||||
theid = htonl(theid);
|
||||
memcpy(temp, &theid, sizeof(theid));
|
||||
memcpy(temp + sizeof(theid), message, length);
|
||||
return write_cryptpacket_id(m, friendnumber, PACKET_ID_MESSAGE, temp, sizeof(temp), 0);
|
||||
return send_message_generic(m, friendnumber, message, length, PACKET_ID_MESSAGE);
|
||||
}
|
||||
|
||||
/* Send an action to an online friend.
|
||||
|
@ -423,32 +498,7 @@ uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid
|
|||
*/
|
||||
uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length)
|
||||
{
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return 0;
|
||||
|
||||
uint32_t msgid = ++m->friendlist[friendnumber].message_id;
|
||||
|
||||
if (msgid == 0)
|
||||
msgid = 1; // Otherwise, false error
|
||||
|
||||
if (m_sendaction_withid(m, friendnumber, msgid, action, length)) {
|
||||
return msgid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t m_sendaction_withid(const Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *action,
|
||||
uint32_t length)
|
||||
{
|
||||
if (length >= (MAX_CRYPTO_DATA_SIZE - sizeof(theid)) || length == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t temp[sizeof(theid) + length];
|
||||
theid = htonl(theid);
|
||||
memcpy(temp, &theid, sizeof(theid));
|
||||
memcpy(temp + sizeof(theid), action, length);
|
||||
return write_cryptpacket_id(m, friendnumber, PACKET_ID_ACTION, temp, sizeof(temp), 0);
|
||||
return send_message_generic(m, friendnumber, action, length, PACKET_ID_ACTION);
|
||||
}
|
||||
|
||||
/* Send a name packet to friendnumber.
|
||||
|
@ -886,18 +936,6 @@ static void set_friend_typing(const Messenger *m, int32_t friendnumber, uint8_t
|
|||
m->friendlist[friendnumber].is_typing = is_typing;
|
||||
}
|
||||
|
||||
/* Sets whether we send read receipts for friendnumber. */
|
||||
void m_set_sends_receipts(Messenger *m, int32_t friendnumber, int yesno)
|
||||
{
|
||||
if (yesno != 0 && yesno != 1)
|
||||
return;
|
||||
|
||||
if (friend_not_valid(m, friendnumber))
|
||||
return;
|
||||
|
||||
m->friendlist[friendnumber].receives_read_receipts = yesno;
|
||||
}
|
||||
|
||||
/* Set the function that will be executed when a friend request is received. */
|
||||
void m_callback_friendrequest(Messenger *m, void (*function)(Messenger *m, const uint8_t *, const uint8_t *, size_t,
|
||||
void *), void *userdata)
|
||||
|
@ -1011,6 +1049,7 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui
|
|||
if (was_online) {
|
||||
break_files(m, friendnumber);
|
||||
remove_online_friend(m, friendnumber);
|
||||
clear_receipts(m, friendnumber);
|
||||
} else {
|
||||
add_online_friend(m, friendnumber);
|
||||
}
|
||||
|
@ -1660,6 +1699,7 @@ void kill_messenger(Messenger *m)
|
|||
|
||||
for (i = 0; i < m->numfriends; ++i) {
|
||||
free(m->friendlist[i].avatar_recv_data);
|
||||
clear_receipts(m, i);
|
||||
}
|
||||
|
||||
free(m->avatar_data);
|
||||
|
@ -2083,23 +2123,18 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
|
|||
|
||||
case PACKET_ID_MESSAGE: {
|
||||
const uint8_t *message_id = data;
|
||||
uint8_t message_id_length = 4;
|
||||
|
||||
if (data_length <= message_id_length)
|
||||
if (data_length == 0)
|
||||
break;
|
||||
|
||||
const uint8_t *message = data + message_id_length;
|
||||
uint16_t message_length = data_length - message_id_length;
|
||||
const uint8_t *message = data;
|
||||
uint16_t message_length = data_length;
|
||||
|
||||
/* Make sure the NULL terminator is present. */
|
||||
uint8_t message_terminated[message_length + 1];
|
||||
memcpy(message_terminated, message, message_length);
|
||||
message_terminated[message_length] = 0;
|
||||
|
||||
if (m->friendlist[i].receives_read_receipts) {
|
||||
write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length, 0);
|
||||
}
|
||||
|
||||
if (m->friend_message)
|
||||
(*m->friend_message)(m, i, message_terminated, message_length, m->friend_message_userdata);
|
||||
|
||||
|
@ -2108,23 +2143,18 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
|
|||
|
||||
case PACKET_ID_ACTION: {
|
||||
const uint8_t *message_id = data;
|
||||
uint8_t message_id_length = 4;
|
||||
|
||||
if (data_length <= message_id_length)
|
||||
if (data_length == 0)
|
||||
break;
|
||||
|
||||
const uint8_t *action = data + message_id_length;
|
||||
uint16_t action_length = data_length - message_id_length;
|
||||
const uint8_t *action = data;
|
||||
uint16_t action_length = data_length;
|
||||
|
||||
/* Make sure the NULL terminator is present. */
|
||||
uint8_t action_terminated[action_length + 1];
|
||||
memcpy(action_terminated, action, action_length);
|
||||
action_terminated[action_length] = 0;
|
||||
|
||||
if (m->friendlist[i].receives_read_receipts) {
|
||||
write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length, 0);
|
||||
}
|
||||
|
||||
if (m->friend_action)
|
||||
(*m->friend_action)(m, i, action_terminated, action_length, m->friend_action_userdata);
|
||||
|
||||
|
@ -2168,21 +2198,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
|
|||
break;
|
||||
}
|
||||
|
||||
case PACKET_ID_RECEIPT: {
|
||||
uint32_t msgid;
|
||||
|
||||
if (data_length < sizeof(msgid))
|
||||
break;
|
||||
|
||||
memcpy(&msgid, data, sizeof(msgid));
|
||||
msgid = ntohl(msgid);
|
||||
|
||||
if (m->read_receipt)
|
||||
(*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PACKET_ID_INVITE_GROUPCHAT: {
|
||||
if (data_length == 0)
|
||||
break;
|
||||
|
@ -2346,6 +2361,7 @@ void do_friends(Messenger *m)
|
|||
}
|
||||
|
||||
check_friend_tcp_udp(m, i);
|
||||
do_receipts(m, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#define PACKET_ID_AVATAR_DATA_CONTROL 54
|
||||
#define PACKET_ID_AVATAR_DATA_START 55
|
||||
#define PACKET_ID_AVATAR_DATA_PUSH 56
|
||||
#define PACKET_ID_RECEIPT 63
|
||||
#define PACKET_ID_MESSAGE 64
|
||||
#define PACKET_ID_ACTION 65
|
||||
#define PACKET_ID_MSI 69
|
||||
|
@ -78,6 +77,13 @@ typedef struct {
|
|||
TCP_Proxy_Info proxy_info;
|
||||
} Messenger_Options;
|
||||
|
||||
|
||||
struct Receipts {
|
||||
uint32_t packet_num;
|
||||
uint32_t msg_id;
|
||||
struct Receipts *next;
|
||||
};
|
||||
|
||||
/* Status definitions. */
|
||||
enum {
|
||||
NOFRIEND,
|
||||
|
@ -217,7 +223,6 @@ typedef struct {
|
|||
uint8_t is_typing;
|
||||
uint16_t info_size; // Length of the info.
|
||||
uint32_t message_id; // a semi-unique id used in read receipts.
|
||||
uint8_t receives_read_receipts; // shall we send read receipts to this person?
|
||||
uint32_t friendrequest_nospam; // The nospam number used in the friend request.
|
||||
uint64_t ping_lastrecv;//TODO remove
|
||||
uint64_t share_relays_lastsent;
|
||||
|
@ -237,6 +242,9 @@ typedef struct {
|
|||
int (*function)(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint32_t len, void *object);
|
||||
void *object;
|
||||
} lossless_packethandlers[PACKET_ID_LOSSLESS_RANGE_SIZE];
|
||||
|
||||
struct Receipts *receipts_start;
|
||||
struct Receipts *receipts_end;
|
||||
} Friend;
|
||||
|
||||
|
||||
|
@ -400,12 +408,8 @@ int m_friend_exists(const Messenger *m, int32_t friendnumber);
|
|||
*
|
||||
* You will want to retain the return value, it will be passed to your read_receipt callback
|
||||
* if one is received.
|
||||
* m_sendmessage_withid will send a message with the id of your choosing,
|
||||
* however we can generate an id for you by calling plain m_sendmessage.
|
||||
*/
|
||||
uint32_t m_sendmessage(Messenger *m, int32_t friendnumber, const uint8_t *message, uint32_t length);
|
||||
uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *message,
|
||||
uint32_t length);
|
||||
|
||||
/* Send an action to an online friend.
|
||||
*
|
||||
|
@ -414,12 +418,8 @@ uint32_t m_sendmessage_withid(Messenger *m, int32_t friendnumber, uint32_t theid
|
|||
*
|
||||
* You will want to retain the return value, it will be passed to your read_receipt callback
|
||||
* if one is received.
|
||||
* m_sendaction_withid will send an action message with the id of your choosing,
|
||||
* however we can generate an id for you by calling plain m_sendaction.
|
||||
*/
|
||||
uint32_t m_sendaction(Messenger *m, int32_t friendnumber, const uint8_t *action, uint32_t length);
|
||||
uint32_t m_sendaction_withid(const Messenger *m, int32_t friendnumber, uint32_t theid, const uint8_t *action,
|
||||
uint32_t length);
|
||||
|
||||
/* Set the name and name_length of a friend.
|
||||
* name must be a string of maximum MAX_NAME_LENGTH length.
|
||||
|
@ -626,11 +626,6 @@ int m_set_usertyping(Messenger *m, int32_t friendnumber, uint8_t is_typing);
|
|||
*/
|
||||
int m_get_istyping(const Messenger *m, int32_t friendnumber);
|
||||
|
||||
/* Sets whether we send read receipts for friendnumber.
|
||||
* This function is not lazy, and it will fail if yesno is not (0 or 1).
|
||||
*/
|
||||
void m_set_sends_receipts(Messenger *m, int32_t friendnumber, int yesno);
|
||||
|
||||
/* Set the function that will be executed when a friend request is received.
|
||||
* Function format is function(uint8_t * public_key, uint8_t * data, size_t length)
|
||||
*/
|
||||
|
|
|
@ -238,7 +238,7 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
|
|||
/**
|
||||
* Maximum length of a single message after which it should be split.
|
||||
*/
|
||||
#define TOX_MAX_MESSAGE_LENGTH 1368
|
||||
#define TOX_MAX_MESSAGE_LENGTH 1372
|
||||
|
||||
/**
|
||||
* Maximum size of custom packets. TODO: should be LENGTH?
|
||||
|
|
Loading…
Reference in New Issue
Block a user