diff options
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r-- | toxcore/Messenger.c | 158 |
1 files changed, 153 insertions, 5 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index c1301767..692d3d0e 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -43,6 +43,71 @@ static uint8_t friend_not_valid(Messenger *m, int friendnumber) | |||
43 | return (unsigned int)friendnumber >= m->numfriends; | 43 | return (unsigned int)friendnumber >= m->numfriends; |
44 | } | 44 | } |
45 | 45 | ||
46 | static int add_online_friend(Messenger *m, int friendnumber) | ||
47 | { | ||
48 | if (friend_not_valid(m, friendnumber)) | ||
49 | return -1; | ||
50 | |||
51 | IP_Port temp_ip_port = get_friend_ipport(m, friendnumber); | ||
52 | |||
53 | if (temp_ip_port.port == 0) | ||
54 | return -1; | ||
55 | |||
56 | uint32_t i; | ||
57 | |||
58 | for (i = 0; i < m->numonline_friends; ++i) { | ||
59 | if (m->online_friendlist[i].friend_num == (uint32_t)friendnumber) | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | Online_Friend *temp; | ||
64 | temp = realloc(m->online_friendlist, sizeof(Online_Friend) * (m->numonline_friends + 1)); | ||
65 | |||
66 | if (temp == NULL) | ||
67 | return -1; | ||
68 | |||
69 | m->online_friendlist = temp; | ||
70 | m->online_friendlist[m->numonline_friends].friend_num = friendnumber; | ||
71 | m->online_friendlist[m->numonline_friends].ip_port = temp_ip_port; | ||
72 | ++m->numonline_friends; | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | |||
77 | static int remove_online_friend(Messenger *m, int friendnumber) | ||
78 | { | ||
79 | uint32_t i; | ||
80 | Online_Friend *temp; | ||
81 | |||
82 | for (i = 0; i < m->numonline_friends; ++i) { | ||
83 | /* Equal */ | ||
84 | if (m->online_friendlist[i].friend_num == (uint32_t)friendnumber) { | ||
85 | --m->numonline_friends; | ||
86 | |||
87 | if (m->numonline_friends != i) { | ||
88 | memcpy( &m->online_friendlist[i], | ||
89 | &m->online_friendlist[m->numonline_friends], | ||
90 | sizeof(Online_Friend) ); | ||
91 | } | ||
92 | |||
93 | if (m->numonline_friends == 0) { | ||
94 | free(m->online_friendlist); | ||
95 | m->online_friendlist = NULL; | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | temp = realloc(m->online_friendlist, sizeof(Online_Friend) * (m->numonline_friends)); | ||
100 | |||
101 | if (temp == NULL) | ||
102 | return -1; | ||
103 | |||
104 | m->online_friendlist = temp; | ||
105 | return 0; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | return -1; | ||
110 | } | ||
46 | /* Set the size of the friend list to numfriends. | 111 | /* Set the size of the friend list to numfriends. |
47 | * | 112 | * |
48 | * return -1 if realloc fails. | 113 | * return -1 if realloc fails. |
@@ -273,6 +338,9 @@ int m_delfriend(Messenger *m, int friendnumber) | |||
273 | if (friend_not_valid(m, friendnumber)) | 338 | if (friend_not_valid(m, friendnumber)) |
274 | return -1; | 339 | return -1; |
275 | 340 | ||
341 | if (m->friendlist[friendnumber].status == FRIEND_ONLINE) | ||
342 | remove_online_friend(m, friendnumber); | ||
343 | |||
276 | onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum); | 344 | onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum); |
277 | crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); | 345 | crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); |
278 | free(m->friendlist[friendnumber].statusmessage); | 346 | free(m->friendlist[friendnumber].statusmessage); |
@@ -650,12 +718,17 @@ void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, in | |||
650 | m->friend_connectionstatuschange = function; | 718 | m->friend_connectionstatuschange = function; |
651 | m->friend_connectionstatuschange_userdata = userdata; | 719 | m->friend_connectionstatuschange_userdata = userdata; |
652 | } | 720 | } |
721 | |||
722 | void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *), | ||
723 | void *userdata) | ||
724 | { | ||
725 | m->friend_connectionstatuschange_internal = function; | ||
726 | m->friend_connectionstatuschange_internal_userdata = userdata; | ||
727 | } | ||
728 | |||
653 | static void break_files(Messenger *m, int friendnumber); | 729 | static void break_files(Messenger *m, int friendnumber); |
654 | static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_t status) | 730 | static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_t status) |
655 | { | 731 | { |
656 | if (!m->friend_connectionstatuschange) | ||
657 | return; | ||
658 | |||
659 | if (status == NOFRIEND) | 732 | if (status == NOFRIEND) |
660 | return; | 733 | return; |
661 | 734 | ||
@@ -665,10 +738,19 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_ | |||
665 | onion_set_friend_online(m->onion_c, m->friendlist[friendnumber].onion_friendnum, is_online); | 738 | onion_set_friend_online(m->onion_c, m->friendlist[friendnumber].onion_friendnum, is_online); |
666 | 739 | ||
667 | if (is_online != was_online) { | 740 | if (is_online != was_online) { |
668 | if (was_online) | 741 | if (was_online) { |
669 | break_files(m, friendnumber); | 742 | break_files(m, friendnumber); |
743 | remove_online_friend(m, friendnumber); | ||
744 | } else { | ||
745 | add_online_friend(m, friendnumber); | ||
746 | } | ||
747 | |||
748 | if (m->friend_connectionstatuschange) | ||
749 | m->friend_connectionstatuschange(m, friendnumber, is_online, m->friend_connectionstatuschange_userdata); | ||
670 | 750 | ||
671 | m->friend_connectionstatuschange(m, friendnumber, is_online, m->friend_connectionstatuschange_userdata); | 751 | if (m->friend_connectionstatuschange_internal) |
752 | m->friend_connectionstatuschange_internal(m, friendnumber, is_online, | ||
753 | m->friend_connectionstatuschange_internal_userdata); | ||
672 | } | 754 | } |
673 | } | 755 | } |
674 | 756 | ||
@@ -814,6 +896,8 @@ static void group_message_function(Group_Chat *chat, int peer_number, uint8_t *m | |||
814 | if (i == -1) | 896 | if (i == -1) |
815 | return; | 897 | return; |
816 | 898 | ||
899 | message[length - 1] = 0; /* Force NULL terminator */ | ||
900 | |||
817 | if (m->group_message) | 901 | if (m->group_message) |
818 | (*m->group_message)(m, i, peer_number, message, length, m->group_message_userdata); | 902 | (*m->group_message)(m, i, peer_number, message, length, m->group_message_userdata); |
819 | } | 903 | } |
@@ -826,6 +910,8 @@ static void group_action_function(Group_Chat *chat, int peer_number, uint8_t *ac | |||
826 | if (i == -1) | 910 | if (i == -1) |
827 | return; | 911 | return; |
828 | 912 | ||
913 | action[length - 1] = 0; /* Force NULL terminator */ | ||
914 | |||
829 | if (m->group_action) | 915 | if (m->group_action) |
830 | (*m->group_action)(m, i, peer_number, action, length, m->group_action_userdata); | 916 | (*m->group_action)(m, i, peer_number, action, length, m->group_action_userdata); |
831 | } | 917 | } |
@@ -1489,6 +1575,60 @@ int m_msi_packet(Messenger *m, int friendnumber, uint8_t *data, uint16_t length) | |||
1489 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length); | 1575 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length); |
1490 | } | 1576 | } |
1491 | 1577 | ||
1578 | static int friendnum_from_ip_port(Messenger *m, IP_Port ip_port) | ||
1579 | { | ||
1580 | uint32_t i; | ||
1581 | |||
1582 | for (i = 0; i < m->numonline_friends; ++i) { | ||
1583 | if (ipport_equal(&m->online_friendlist[i].ip_port, &ip_port)) | ||
1584 | return m->online_friendlist[i].friend_num; | ||
1585 | } | ||
1586 | |||
1587 | return -1; | ||
1588 | } | ||
1589 | |||
1590 | static int handle_custom_user_packet(void *object, IP_Port source, uint8_t *packet, uint32_t length) | ||
1591 | { | ||
1592 | Messenger *m = object; | ||
1593 | int friend_num = friendnum_from_ip_port(m, source); | ||
1594 | |||
1595 | if (friend_num == -1) | ||
1596 | return 1; | ||
1597 | |||
1598 | if (m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].function) | ||
1599 | return m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].function( | ||
1600 | m->friendlist[friend_num].packethandlers[packet[0] % TOTAL_USERPACKETS].object, source, packet, length); | ||
1601 | |||
1602 | return 1; | ||
1603 | } | ||
1604 | |||
1605 | |||
1606 | int custom_user_packet_registerhandler(Messenger *m, int friendnumber, uint8_t byte, packet_handler_callback cb, | ||
1607 | void *object) | ||
1608 | { | ||
1609 | if (friend_not_valid(m, friendnumber)) | ||
1610 | return -1; | ||
1611 | |||
1612 | if (byte < NET_PACKET_CUSTOM_RANGE_START || byte >= NET_PACKET_CUSTOM_RANGE_END) | ||
1613 | return -1; | ||
1614 | |||
1615 | m->friendlist[friendnumber].packethandlers[byte % TOTAL_USERPACKETS].function = cb; | ||
1616 | m->friendlist[friendnumber].packethandlers[byte % TOTAL_USERPACKETS].object = object; | ||
1617 | networking_registerhandler(m->net, byte, handle_custom_user_packet, m); | ||
1618 | return 0; | ||
1619 | } | ||
1620 | |||
1621 | int send_custom_user_packet(Messenger *m, int friendnumber, uint8_t *data, uint32_t length) | ||
1622 | { | ||
1623 | IP_Port ip_port = get_friend_ipport(m, friendnumber); | ||
1624 | |||
1625 | if (ip_port.port == 0) | ||
1626 | return -1; | ||
1627 | |||
1628 | return sendpacket(m->net, ip_port, data, length); | ||
1629 | } | ||
1630 | |||
1631 | |||
1492 | /* Function to filter out some friend requests*/ | 1632 | /* Function to filter out some friend requests*/ |
1493 | static int friend_already_added(uint8_t *client_id, void *data) | 1633 | static int friend_already_added(uint8_t *client_id, void *data) |
1494 | { | 1634 | { |
@@ -1841,6 +1981,8 @@ void do_friends(Messenger *m) | |||
1841 | m->friendlist[i].file_receiving[filenumber].size = filesize; | 1981 | m->friendlist[i].file_receiving[filenumber].size = filesize; |
1842 | m->friendlist[i].file_receiving[filenumber].transferred = 0; | 1982 | m->friendlist[i].file_receiving[filenumber].transferred = 0; |
1843 | 1983 | ||
1984 | data[data_length - 1] = 0; /* Force NULL terminate file name. */ | ||
1985 | |||
1844 | if (m->file_sendrequest) | 1986 | if (m->file_sendrequest) |
1845 | (*m->file_sendrequest)(m, i, filenumber, filesize, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t), | 1987 | (*m->file_sendrequest)(m, i, filenumber, filesize, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t), |
1846 | m->file_sendrequest_userdata); | 1988 | m->file_sendrequest_userdata); |
@@ -2360,6 +2502,12 @@ uint32_t count_friendlist(Messenger *m) | |||
2360 | return ret; | 2502 | return ret; |
2361 | } | 2503 | } |
2362 | 2504 | ||
2505 | /* Return the number of online friends in the instance m. */ | ||
2506 | uint32_t get_num_online_friends(Messenger *m) | ||
2507 | { | ||
2508 | return m->numonline_friends; | ||
2509 | } | ||
2510 | |||
2363 | /* Copy a list of valid friend IDs into the array out_list. | 2511 | /* Copy a list of valid friend IDs into the array out_list. |
2364 | * If out_list is NULL, returns 0. | 2512 | * If out_list is NULL, returns 0. |
2365 | * Otherwise, returns the number of elements copied. | 2513 | * Otherwise, returns the number of elements copied. |