diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/Messenger.h | 3 | ||||
-rw-r--r-- | toxcore/friend_connection.c | 16 | ||||
-rw-r--r-- | toxcore/friend_connection.h | 5 | ||||
-rw-r--r-- | toxcore/group.c | 259 | ||||
-rw-r--r-- | toxcore/group.h | 11 | ||||
-rw-r--r-- | toxcore/state.h | 1 | ||||
-rw-r--r-- | toxcore/tox.c | 1 |
7 files changed, 287 insertions, 9 deletions
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 1651315e..a3376e23 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -796,6 +796,9 @@ uint8_t *messenger_save(const Messenger *m, uint8_t *data); | |||
796 | 796 | ||
797 | /* Load a state section. | 797 | /* Load a state section. |
798 | * | 798 | * |
799 | * @param data Data to load. | ||
800 | * @param length Length of data. | ||
801 | * @param type Type of section (STATE_TYPE_*). | ||
799 | * @param status Result of loading section is stored here if the section is handled. | 802 | * @param status Result of loading section is stored here if the section is handled. |
800 | * @return true iff section handled. | 803 | * @return true iff section handled. |
801 | */ | 804 | */ |
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index 9c805b45..69533def 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c | |||
@@ -85,6 +85,9 @@ struct Friend_Connections { | |||
85 | fr_request_cb *fr_request_callback; | 85 | fr_request_cb *fr_request_callback; |
86 | void *fr_request_object; | 86 | void *fr_request_object; |
87 | 87 | ||
88 | global_status_cb *global_status_callback; | ||
89 | void *global_status_callback_object; | ||
90 | |||
88 | uint64_t last_lan_discovery; | 91 | uint64_t last_lan_discovery; |
89 | uint16_t next_lan_port; | 92 | uint16_t next_lan_port; |
90 | 93 | ||
@@ -401,9 +404,11 @@ static int handle_status(void *object, int number, uint8_t status, void *userdat | |||
401 | } | 404 | } |
402 | 405 | ||
403 | if (status_changed) { | 406 | if (status_changed) { |
404 | unsigned int i; | 407 | if (fr_c->global_status_callback) { |
408 | fr_c->global_status_callback(fr_c->global_status_callback_object, number, status, userdata); | ||
409 | } | ||
405 | 410 | ||
406 | for (i = 0; i < MAX_FRIEND_CONNECTION_CALLBACKS; ++i) { | 411 | for (unsigned i = 0; i < MAX_FRIEND_CONNECTION_CALLBACKS; ++i) { |
407 | if (friend_con->callbacks[i].status_callback) { | 412 | if (friend_con->callbacks[i].status_callback) { |
408 | friend_con->callbacks[i].status_callback( | 413 | friend_con->callbacks[i].status_callback( |
409 | friend_con->callbacks[i].callback_object, | 414 | friend_con->callbacks[i].callback_object, |
@@ -716,6 +721,13 @@ int friend_connection_callbacks(Friend_Connections *fr_c, int friendcon_id, unsi | |||
716 | return 0; | 721 | return 0; |
717 | } | 722 | } |
718 | 723 | ||
724 | /* Set global status callback for friend connections. */ | ||
725 | void set_global_status_callback(Friend_Connections *fr_c, global_status_cb *global_status_callback, void *object) | ||
726 | { | ||
727 | fr_c->global_status_callback = global_status_callback; | ||
728 | fr_c->global_status_callback_object = object; | ||
729 | } | ||
730 | |||
719 | /* return the crypt_connection_id for the connection. | 731 | /* return the crypt_connection_id for the connection. |
720 | * | 732 | * |
721 | * return crypt_connection_id on success. | 733 | * return crypt_connection_id on success. |
diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h index 149a4fa7..166c731b 100644 --- a/toxcore/friend_connection.h +++ b/toxcore/friend_connection.h | |||
@@ -101,10 +101,15 @@ void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t * | |||
101 | */ | 101 | */ |
102 | int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key); | 102 | int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key); |
103 | 103 | ||
104 | typedef int global_status_cb(void *object, int id, uint8_t status, void *userdata); | ||
105 | |||
104 | typedef int fc_status_cb(void *object, int id, uint8_t status, void *userdata); | 106 | typedef int fc_status_cb(void *object, int id, uint8_t status, void *userdata); |
105 | typedef int fc_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); | 107 | typedef int fc_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); |
106 | typedef int fc_lossy_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); | 108 | typedef int fc_lossy_data_cb(void *object, int id, const uint8_t *data, uint16_t length, void *userdata); |
107 | 109 | ||
110 | /* Set global status callback for friend connections. */ | ||
111 | void set_global_status_callback(Friend_Connections *fr_c, global_status_cb *global_status_callback, void *object); | ||
112 | |||
108 | /* Set the callbacks for the friend connection. | 113 | /* Set the callbacks for the friend connection. |
109 | * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array. | 114 | * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array. |
110 | * | 115 | * |
diff --git a/toxcore/group.c b/toxcore/group.c index 9ef32b72..99f72336 100644 --- a/toxcore/group.c +++ b/toxcore/group.c | |||
@@ -27,10 +27,12 @@ | |||
27 | 27 | ||
28 | #include "group.h" | 28 | #include "group.h" |
29 | 29 | ||
30 | #include <assert.h> | ||
30 | #include <stdlib.h> | 31 | #include <stdlib.h> |
31 | #include <string.h> | 32 | #include <string.h> |
32 | 33 | ||
33 | #include "mono_time.h" | 34 | #include "mono_time.h" |
35 | #include "state.h" | ||
34 | #include "util.h" | 36 | #include "util.h" |
35 | 37 | ||
36 | /** | 38 | /** |
@@ -880,13 +882,23 @@ static void rejoin_frozen_friend(Group_Chats *g_c, int friendcon_id) | |||
880 | } | 882 | } |
881 | } | 883 | } |
882 | 884 | ||
885 | static int g_handle_any_status(void *object, int friendcon_id, uint8_t status, void *userdata) | ||
886 | { | ||
887 | Group_Chats *g_c = (Group_Chats *)object; | ||
888 | |||
889 | if (status) { | ||
890 | rejoin_frozen_friend(g_c, friendcon_id); | ||
891 | } | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
883 | static int g_handle_status(void *object, int friendcon_id, uint8_t status, void *userdata) | 896 | static int g_handle_status(void *object, int friendcon_id, uint8_t status, void *userdata) |
884 | { | 897 | { |
885 | Group_Chats *g_c = (Group_Chats *)object; | 898 | Group_Chats *g_c = (Group_Chats *)object; |
886 | 899 | ||
887 | if (status) { /* Went online */ | 900 | if (status) { /* Went online */ |
888 | set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_ONLINE, userdata); | 901 | set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_ONLINE, userdata); |
889 | rejoin_frozen_friend(g_c, friendcon_id); | ||
890 | } else { /* Went offline */ | 902 | } else { /* Went offline */ |
891 | set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_CONNECTION, userdata); | 903 | set_conns_status_groups(g_c, friendcon_id, GROUPCHAT_CLOSE_CONNECTION, userdata); |
892 | // TODO(irungentoo): remove timedout connections? | 904 | // TODO(irungentoo): remove timedout connections? |
@@ -1021,7 +1033,6 @@ int add_groupchat(Group_Chats *g_c, uint8_t type) | |||
1021 | return groupnumber; | 1033 | return groupnumber; |
1022 | } | 1034 | } |
1023 | 1035 | ||
1024 | static int group_kill_peer_send(const Group_Chats *g_c, uint32_t groupnumber, uint16_t peer_num); | ||
1025 | /* Delete a groupchat from the chats array. | 1036 | /* Delete a groupchat from the chats array. |
1026 | * | 1037 | * |
1027 | * return 0 on success. | 1038 | * return 0 on success. |
@@ -1035,8 +1046,6 @@ int del_groupchat(Group_Chats *g_c, uint32_t groupnumber) | |||
1035 | return -1; | 1046 | return -1; |
1036 | } | 1047 | } |
1037 | 1048 | ||
1038 | group_kill_peer_send(g_c, groupnumber, g->peer_number); | ||
1039 | |||
1040 | for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { | 1049 | for (uint32_t i = 0; i < MAX_GROUP_CONNECTIONS; ++i) { |
1041 | if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { | 1050 | if (g->close[i].type == GROUPCHAT_CLOSE_NONE) { |
1042 | continue; | 1051 | continue; |
@@ -1587,6 +1596,22 @@ static int group_name_send(const Group_Chats *g_c, uint32_t groupnumber, const u | |||
1587 | return -1; | 1596 | return -1; |
1588 | } | 1597 | } |
1589 | 1598 | ||
1599 | /* send message to announce leaving group | ||
1600 | * return true on success | ||
1601 | * return false on failure | ||
1602 | */ | ||
1603 | bool group_leave(const Group_Chats *g_c, uint32_t groupnumber) | ||
1604 | { | ||
1605 | Group_c *g = get_group_c(g_c, groupnumber); | ||
1606 | |||
1607 | if (!g) { | ||
1608 | return false; | ||
1609 | } | ||
1610 | |||
1611 | return group_kill_peer_send(g_c, groupnumber, g->peer_number) == 0; | ||
1612 | } | ||
1613 | |||
1614 | |||
1590 | /* set the group's title, limited to MAX_NAME_LENGTH | 1615 | /* set the group's title, limited to MAX_NAME_LENGTH |
1591 | * return 0 on success | 1616 | * return 0 on success |
1592 | * return -1 if groupnumber is invalid. | 1617 | * return -1 if groupnumber is invalid. |
@@ -2875,22 +2900,242 @@ void send_name_all_groups(Group_Chats *g_c) | |||
2875 | } | 2900 | } |
2876 | } | 2901 | } |
2877 | 2902 | ||
2903 | #define SAVED_PEER_SIZE_CONSTANT (2 * CRYPTO_PUBLIC_KEY_SIZE + 2 + 1) | ||
2904 | |||
2905 | static uint32_t saved_peer_size(const Group_Peer *peer) | ||
2906 | { | ||
2907 | return SAVED_PEER_SIZE_CONSTANT + peer->nick_len; | ||
2908 | } | ||
2909 | |||
2910 | static uint8_t *save_peer(const Group_Peer *peer, uint8_t *data) | ||
2911 | { | ||
2912 | memcpy(data, peer->real_pk, CRYPTO_PUBLIC_KEY_SIZE); | ||
2913 | data += CRYPTO_PUBLIC_KEY_SIZE; | ||
2914 | |||
2915 | memcpy(data, peer->temp_pk, CRYPTO_PUBLIC_KEY_SIZE); | ||
2916 | data += CRYPTO_PUBLIC_KEY_SIZE; | ||
2917 | |||
2918 | host_to_lendian_bytes16(data, peer->peer_number); | ||
2919 | data += sizeof(uint16_t); | ||
2920 | |||
2921 | *data = peer->nick_len; | ||
2922 | ++data; | ||
2923 | |||
2924 | memcpy(data, peer->nick, peer->nick_len); | ||
2925 | data += peer->nick_len; | ||
2926 | |||
2927 | return data; | ||
2928 | } | ||
2929 | |||
2930 | #define SAVED_CONF_SIZE_CONSTANT (1 + GROUP_ID_LENGTH + sizeof(uint32_t) \ | ||
2931 | + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + 1) | ||
2932 | |||
2933 | static uint32_t saved_conf_size(const Group_c *g) | ||
2934 | { | ||
2935 | uint32_t len = SAVED_CONF_SIZE_CONSTANT + g->title_len; | ||
2936 | |||
2937 | for (uint32_t j = 0; j < g->numpeers + g->numfrozen; ++j) { | ||
2938 | const Group_Peer *peer = (j < g->numpeers) ? &g->group[j] : &g->frozen[j - g->numpeers]; | ||
2939 | |||
2940 | if (id_equal(peer->real_pk, g->real_pk)) { | ||
2941 | continue; | ||
2942 | } | ||
2943 | |||
2944 | len += saved_peer_size(peer); | ||
2945 | } | ||
2946 | |||
2947 | return len; | ||
2948 | } | ||
2949 | |||
2950 | static uint8_t *save_conf(const Group_c *g, uint8_t *data) | ||
2951 | { | ||
2952 | *data = g->type; | ||
2953 | ++data; | ||
2954 | |||
2955 | memcpy(data, g->id, GROUP_ID_LENGTH); | ||
2956 | data += GROUP_ID_LENGTH; | ||
2957 | |||
2958 | host_to_lendian_bytes32(data, g->message_number); | ||
2959 | data += sizeof(uint32_t); | ||
2960 | |||
2961 | host_to_lendian_bytes16(data, g->lossy_message_number); | ||
2962 | data += sizeof(uint16_t); | ||
2963 | |||
2964 | host_to_lendian_bytes16(data, g->peer_number); | ||
2965 | data += sizeof(uint16_t); | ||
2966 | |||
2967 | host_to_lendian_bytes32(data, g->numpeers - 1 + g->numfrozen); | ||
2968 | data += sizeof(uint32_t); | ||
2969 | |||
2970 | *data = g->title_len; | ||
2971 | ++data; | ||
2972 | |||
2973 | memcpy(data, g->title, g->title_len); | ||
2974 | data += g->title_len; | ||
2975 | |||
2976 | #ifndef NDEBUG | ||
2977 | bool found_self = false; | ||
2978 | #endif | ||
2979 | |||
2980 | for (uint32_t j = 0; j < g->numpeers + g->numfrozen; ++j) { | ||
2981 | const Group_Peer *peer = (j < g->numpeers) ? &g->group[j] : &g->frozen[j - g->numpeers]; | ||
2982 | |||
2983 | if (id_equal(peer->real_pk, g->real_pk)) { | ||
2984 | #ifndef NDEBUG | ||
2985 | found_self = true; | ||
2986 | #endif | ||
2987 | continue; | ||
2988 | } | ||
2989 | |||
2990 | data = save_peer(peer, data); | ||
2991 | } | ||
2992 | |||
2993 | assert(found_self); | ||
2994 | |||
2995 | return data; | ||
2996 | } | ||
2997 | |||
2998 | static uint32_t conferences_section_size(const Group_Chats *g_c) | ||
2999 | { | ||
3000 | uint32_t len = 0; | ||
3001 | |||
3002 | for (uint16_t i = 0; i < g_c->num_chats; ++i) { | ||
3003 | Group_c *g = get_group_c(g_c, i); | ||
3004 | |||
3005 | if (!g || g->status != GROUPCHAT_STATUS_CONNECTED) { | ||
3006 | continue; | ||
3007 | } | ||
3008 | |||
3009 | len += saved_conf_size(g); | ||
3010 | } | ||
3011 | |||
3012 | return len; | ||
3013 | } | ||
3014 | |||
2878 | uint32_t conferences_size(const Group_Chats *g_c) | 3015 | uint32_t conferences_size(const Group_Chats *g_c) |
2879 | { | 3016 | { |
2880 | return 0; | 3017 | return 2 * sizeof(uint32_t) + conferences_section_size(g_c); |
2881 | } | 3018 | } |
2882 | 3019 | ||
2883 | uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data) | 3020 | uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data) |
2884 | { | 3021 | { |
3022 | const uint32_t len = conferences_section_size(g_c); | ||
3023 | data = state_write_section_header(data, STATE_COOKIE_TYPE, len, STATE_TYPE_CONFERENCES); | ||
3024 | |||
3025 | for (uint16_t i = 0; i < g_c->num_chats; ++i) { | ||
3026 | Group_c *g = get_group_c(g_c, i); | ||
3027 | |||
3028 | if (!g || g->status != GROUPCHAT_STATUS_CONNECTED) { | ||
3029 | continue; | ||
3030 | } | ||
3031 | |||
3032 | data = save_conf(g, data); | ||
3033 | } | ||
3034 | |||
2885 | return data; | 3035 | return data; |
2886 | } | 3036 | } |
2887 | 3037 | ||
3038 | static State_Load_Status load_conferences(Group_Chats *g_c, const uint8_t *data, uint32_t length) | ||
3039 | { | ||
3040 | const uint8_t *init_data = data; | ||
3041 | |||
3042 | while (length >= (uint32_t)(data - init_data) + SAVED_CONF_SIZE_CONSTANT) { | ||
3043 | const int groupnumber = create_group_chat(g_c); | ||
3044 | |||
3045 | if (groupnumber == -1) { | ||
3046 | return STATE_LOAD_STATUS_ERROR; | ||
3047 | } | ||
3048 | |||
3049 | Group_c *g = &g_c->chats[groupnumber]; | ||
3050 | |||
3051 | g->type = *data; | ||
3052 | ++data; | ||
3053 | |||
3054 | memcpy(g->id, data, GROUP_ID_LENGTH); | ||
3055 | data += GROUP_ID_LENGTH; | ||
3056 | |||
3057 | lendian_bytes_to_host32(&g->message_number, data); | ||
3058 | data += sizeof(uint32_t); | ||
3059 | |||
3060 | lendian_bytes_to_host16(&g->lossy_message_number, data); | ||
3061 | data += sizeof(uint16_t); | ||
3062 | |||
3063 | lendian_bytes_to_host16(&g->peer_number, data); | ||
3064 | data += sizeof(uint16_t); | ||
3065 | |||
3066 | lendian_bytes_to_host32(&g->numfrozen, data); | ||
3067 | data += sizeof(uint32_t); | ||
3068 | |||
3069 | g->frozen = (Group_Peer *)malloc(sizeof(Group_Peer) * g->numfrozen); | ||
3070 | |||
3071 | if (g->frozen == nullptr) { | ||
3072 | return STATE_LOAD_STATUS_ERROR; | ||
3073 | } | ||
3074 | |||
3075 | g->title_len = *data; | ||
3076 | ++data; | ||
3077 | |||
3078 | if (length < (uint32_t)(data - init_data) + g->title_len) { | ||
3079 | return STATE_LOAD_STATUS_ERROR; | ||
3080 | } | ||
3081 | |||
3082 | memcpy(g->title, data, g->title_len); | ||
3083 | data += g->title_len; | ||
3084 | |||
3085 | for (uint32_t j = 0; j < g->numfrozen; ++j) { | ||
3086 | if (length < (uint32_t)(data - init_data) + SAVED_PEER_SIZE_CONSTANT) { | ||
3087 | return STATE_LOAD_STATUS_ERROR; | ||
3088 | } | ||
3089 | |||
3090 | Group_Peer *peer = &g->frozen[j]; | ||
3091 | memset(peer, 0, sizeof(Group_Peer)); | ||
3092 | |||
3093 | id_copy(peer->real_pk, data); | ||
3094 | data += CRYPTO_PUBLIC_KEY_SIZE; | ||
3095 | id_copy(peer->temp_pk, data); | ||
3096 | data += CRYPTO_PUBLIC_KEY_SIZE; | ||
3097 | |||
3098 | lendian_bytes_to_host16(&peer->peer_number, data); | ||
3099 | data += sizeof(uint16_t); | ||
3100 | |||
3101 | peer->nick_len = *data; | ||
3102 | ++data; | ||
3103 | |||
3104 | if (length < (uint32_t)(data - init_data) + peer->nick_len) { | ||
3105 | return STATE_LOAD_STATUS_ERROR; | ||
3106 | } | ||
3107 | |||
3108 | memcpy(peer->nick, data, peer->nick_len); | ||
3109 | data += peer->nick_len; | ||
3110 | } | ||
3111 | |||
3112 | g->status = GROUPCHAT_STATUS_CONNECTED; | ||
3113 | memcpy(g->real_pk, nc_get_self_public_key(g_c->m->net_crypto), CRYPTO_PUBLIC_KEY_SIZE); | ||
3114 | const int peer_index = addpeer(g_c, groupnumber, g->real_pk, dht_get_self_public_key(g_c->m->dht), g->peer_number, | ||
3115 | nullptr, true, false); | ||
3116 | |||
3117 | if (peer_index == -1) { | ||
3118 | return STATE_LOAD_STATUS_ERROR; | ||
3119 | } | ||
3120 | |||
3121 | setnick(g_c, groupnumber, peer_index, g_c->m->name, g_c->m->name_length, nullptr, false); | ||
3122 | } | ||
3123 | |||
3124 | return STATE_LOAD_STATUS_CONTINUE; | ||
3125 | } | ||
3126 | |||
2888 | bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint32_t length, uint16_t type, | 3127 | bool conferences_load_state_section(Group_Chats *g_c, const uint8_t *data, uint32_t length, uint16_t type, |
2889 | State_Load_Status *status) | 3128 | State_Load_Status *status) |
2890 | { | 3129 | { |
2891 | return false; | 3130 | if (type != STATE_TYPE_CONFERENCES) { |
3131 | return false; | ||
3132 | } | ||
3133 | |||
3134 | *status = load_conferences(g_c, data, length); | ||
3135 | return true; | ||
2892 | } | 3136 | } |
2893 | 3137 | ||
3138 | |||
2894 | /* Create new groupchat instance. */ | 3139 | /* Create new groupchat instance. */ |
2895 | Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m) | 3140 | Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m) |
2896 | { | 3141 | { |
@@ -2910,6 +3155,8 @@ Group_Chats *new_groupchats(Mono_Time *mono_time, Messenger *m) | |||
2910 | m->conferences_object = temp; | 3155 | m->conferences_object = temp; |
2911 | m_callback_conference_invite(m, &handle_friend_invite_packet); | 3156 | m_callback_conference_invite(m, &handle_friend_invite_packet); |
2912 | 3157 | ||
3158 | set_global_status_callback(m->fr_c, &g_handle_any_status, temp); | ||
3159 | |||
2913 | return temp; | 3160 | return temp; |
2914 | } | 3161 | } |
2915 | 3162 | ||
diff --git a/toxcore/group.h b/toxcore/group.h index 8673abdb..148de0c1 100644 --- a/toxcore/group.h +++ b/toxcore/group.h | |||
@@ -306,6 +306,12 @@ int group_message_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8 | |||
306 | */ | 306 | */ |
307 | int group_action_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *action, uint16_t length); | 307 | int group_action_send(const Group_Chats *g_c, uint32_t groupnumber, const uint8_t *action, uint16_t length); |
308 | 308 | ||
309 | /* send message to announce leaving group | ||
310 | * return true on success | ||
311 | * return false on failure | ||
312 | */ | ||
313 | bool group_leave(const Group_Chats *g_c, uint32_t groupnumber); | ||
314 | |||
309 | /* set the group's title, limited to MAX_NAME_LENGTH | 315 | /* set the group's title, limited to MAX_NAME_LENGTH |
310 | * return 0 on success | 316 | * return 0 on success |
311 | * return -1 if groupnumber is invalid. | 317 | * return -1 if groupnumber is invalid. |
@@ -455,8 +461,11 @@ uint32_t conferences_size(const Group_Chats *g_c); | |||
455 | uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data); | 461 | uint8_t *conferences_save(const Group_Chats *g_c, uint8_t *data); |
456 | 462 | ||
457 | /** | 463 | /** |
458 | * Load a section. | 464 | * Load a state section. |
459 | * | 465 | * |
466 | * @param data Data to load | ||
467 | * @param length Length of data | ||
468 | * @param type Type of section (STATE_TYPE_*) | ||
460 | * @param status Result of loading section is stored here if the section is handled. | 469 | * @param status Result of loading section is stored here if the section is handled. |
461 | * @return true iff section handled. | 470 | * @return true iff section handled. |
462 | */ | 471 | */ |
diff --git a/toxcore/state.h b/toxcore/state.h index 872b1e9d..6e3c897e 100644 --- a/toxcore/state.h +++ b/toxcore/state.h | |||
@@ -31,6 +31,7 @@ typedef enum State_Type { | |||
31 | STATE_TYPE_STATUS = 6, | 31 | STATE_TYPE_STATUS = 6, |
32 | STATE_TYPE_TCP_RELAY = 10, | 32 | STATE_TYPE_TCP_RELAY = 10, |
33 | STATE_TYPE_PATH_NODE = 11, | 33 | STATE_TYPE_PATH_NODE = 11, |
34 | STATE_TYPE_CONFERENCES = 20, | ||
34 | STATE_TYPE_END = 255, | 35 | STATE_TYPE_END = 255, |
35 | } State_Type; | 36 | } State_Type; |
36 | 37 | ||
diff --git a/toxcore/tox.c b/toxcore/tox.c index 629cc1c5..88a9bd50 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -1533,6 +1533,7 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error) | |||
1533 | bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Conference_Delete *error) | 1533 | bool tox_conference_delete(Tox *tox, uint32_t conference_number, Tox_Err_Conference_Delete *error) |
1534 | { | 1534 | { |
1535 | Messenger *m = tox->m; | 1535 | Messenger *m = tox->m; |
1536 | group_leave(m->conferences_object, conference_number); | ||
1536 | int ret = del_groupchat(m->conferences_object, conference_number); | 1537 | int ret = del_groupchat(m->conferences_object, conference_number); |
1537 | 1538 | ||
1538 | if (ret == -1) { | 1539 | if (ret == -1) { |