From 7d1060abc2d6bd19cdedcdc6f783076f7d912bff Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Thu, 13 Mar 2014 20:20:48 -0400 Subject: [PATCH 1/2] add api function that gets the last time a friend was seen online --- toxcore/Messenger.c | 24 +++++++++++++++++++++--- toxcore/Messenger.h | 6 +++++- toxcore/tox.c | 10 +++++++++- toxcore/tox.h | 7 ++++++- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 9d5fe22a..b97644a5 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -276,7 +276,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); if (m->numfriends == i) - ++ m->numfriends; + ++m->numfriends; return i; } @@ -321,7 +321,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id) m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ if (m->numfriends == i) - ++ m->numfriends; + ++m->numfriends; return i; } @@ -617,6 +617,14 @@ USERSTATUS m_get_self_userstatus(Messenger *m) return m->userstatus; } +uint64_t m_get_last_online(Messenger *m, int friendnumber) +{ + if (friend_not_valid(m, friendnumber)) + return -1; + + return m->friendlist[friendnumber].ping_lastrecv; +} + int m_set_usertyping(Messenger *m, int friendnumber, uint8_t is_typing) { if (is_typing != 0 && is_typing != 1) { @@ -2353,6 +2361,7 @@ struct SAVED_FRIEND { uint16_t statusmessage_length; uint8_t userstatus; uint32_t friendrequest_nospam; + uint64_t ping_lastrecv; }; static uint32_t saved_friendslist_size(Messenger *m) @@ -2382,6 +2391,11 @@ static uint32_t friends_list_save(Messenger *m, uint8_t *data) memcpy(temp.statusmessage, m->friendlist[i].statusmessage, m->friendlist[i].statusmessage_length); temp.statusmessage_length = htons(m->friendlist[i].statusmessage_length); temp.userstatus = m->friendlist[i].userstatus; + + uint8_t lastonline[sizeof(uint64_t)]; + memcpy(lastonline, &m->friendlist[i].ping_lastrecv, sizeof(uint64_t)); + host_to_net(lastonline, sizeof(uint64_t)); + memcpy(&temp.ping_lastrecv, lastonline, sizeof(uint64_t)); } memcpy(data + num * sizeof(struct SAVED_FRIEND), &temp, sizeof(struct SAVED_FRIEND)); @@ -2409,6 +2423,11 @@ static int friends_list_load(Messenger *m, uint8_t *data, uint32_t length) setfriendname(m, fnum, temp.name, ntohs(temp.name_length)); set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length)); set_friend_userstatus(m, fnum, temp.userstatus); + + uint8_t lastonline[sizeof(uint64_t)]; + memcpy(lastonline, &temp.ping_lastrecv, sizeof(uint64_t)); + net_to_host(lastonline, sizeof(uint64_t)); + memcpy(&m->friendlist[fnum].ping_lastrecv, lastonline, sizeof(uint64_t)); } else if (temp.status != 0) { /* TODO: This is not a good way to do this. */ uint8_t address[FRIEND_ADDRESS_SIZE]; @@ -2852,4 +2871,3 @@ uint32_t copy_chatlist(Messenger *m, int *out_list, uint32_t list_size) return ret; } - diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index e6851800..f1a527ec 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -404,6 +404,11 @@ int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen); USERSTATUS m_get_userstatus(Messenger *m, int friendnumber); USERSTATUS m_get_self_userstatus(Messenger *m); +/* returns timestamp of last time friendnumber was seen online, or 0 if never seen. + * returns -1 on error. + */ +uint64_t m_get_last_online(Messenger *m, int friendnumber); + /* Set our typing status for a friend. * You are responsible for turning it on or off. * @@ -770,4 +775,3 @@ uint32_t count_chatlist(Messenger *m); uint32_t copy_chatlist(Messenger *m, int *out_list, uint32_t list_size); #endif - diff --git a/toxcore/tox.c b/toxcore/tox.c index 0115e827..ce4bd996 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -270,6 +270,15 @@ TOX_USERSTATUS tox_get_self_user_status(Tox *tox) return (TOX_USERSTATUS)m_get_self_userstatus(m); } +/* returns timestamp of last time friendnumber was seen online, or 0 if never seen. + * returns -1 on error. + */ +uint64_t tox_get_last_online(Tox *tox, int friendnumber) +{ + Messenger *m = tox; + return m_get_last_online(m, friendnumber); +} + /* Set our typing status for a friend. * You are responsible for turning it on or off. * @@ -293,7 +302,6 @@ int tox_get_is_typing(Tox *tox, int friendnumber) return m_get_istyping(m, 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). */ diff --git a/toxcore/tox.h b/toxcore/tox.h index 3dee2b6e..1bc16c32 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -280,6 +280,12 @@ int tox_get_self_status_message(Tox *tox, uint8_t *buf, uint32_t maxlen); TOX_USERSTATUS tox_get_user_status(Tox *tox, int friendnumber); TOX_USERSTATUS tox_get_self_user_status(Tox *tox); + +/* returns timestamp of last time friendnumber was seen online, or 0 if never seen. + * returns -1 on error. + */ +uint64_t tox_get_last_online(Tox *tox, int friendnumber); + /* Set our typing status for a friend. * You are responsible for turning it on or off. * @@ -726,4 +732,3 @@ int tox_load_encrypted(Tox *tox, uint8_t *data, uint32_t length, uint8_t *key, u #endif #endif - From 419a2fb2e319b1b9bf297cb26e0c448bad54b32b Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Sun, 16 Mar 2014 05:09:36 -0400 Subject: [PATCH 2/2] retain old data file friendlists on load --- toxcore/Messenger.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index b97644a5..6e476e6e 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -2364,6 +2364,21 @@ struct SAVED_FRIEND { uint64_t ping_lastrecv; }; +/* for backwards compatibility with last version of SAVED_FRIEND. + must never be bigger than SAVED_FRIEND. */ +struct SAVED_FRIEND_OLD { + uint8_t status; + uint8_t client_id[CLIENT_ID_SIZE]; + uint8_t info[MAX_DATA_SIZE]; + uint16_t info_size; + uint8_t name[MAX_NAME_LENGTH]; + uint16_t name_length; + uint8_t statusmessage[MAX_STATUSMESSAGE_LENGTH]; + uint16_t statusmessage_length; + uint8_t userstatus; + uint32_t friendrequest_nospam; +}; + static uint32_t saved_friendslist_size(Messenger *m) { return count_friendlist(m) * sizeof(struct SAVED_FRIEND); @@ -2408,15 +2423,24 @@ static uint32_t friends_list_save(Messenger *m, uint8_t *data) static int friends_list_load(Messenger *m, uint8_t *data, uint32_t length) { - if (length % sizeof(struct SAVED_FRIEND) != 0) - return -1; + int old_data = 0; - uint32_t num = length / sizeof(struct SAVED_FRIEND); + if (length % sizeof(struct SAVED_FRIEND) != 0) { + if (length % sizeof(struct SAVED_FRIEND_OLD) != 0) + return -1; + + old_data = 1; + } + + /* if old data file is being used, offset size of current SAVED_FRIEND struct with size of old one */ + uint32_t diff = old_data ? sizeof(struct SAVED_FRIEND) - sizeof(struct SAVED_FRIEND_OLD) : 0; + uint32_t struct_size = sizeof(struct SAVED_FRIEND) - diff; + uint32_t num = length / struct_size; uint32_t i; for (i = 0; i < num; ++i) { struct SAVED_FRIEND temp; - memcpy(&temp, data + i * sizeof(struct SAVED_FRIEND), sizeof(struct SAVED_FRIEND)); + memcpy(&temp, data + i * struct_size, struct_size); if (temp.status >= 3) { int fnum = m_addfriend_norequest(m, temp.client_id); @@ -2424,10 +2448,12 @@ static int friends_list_load(Messenger *m, uint8_t *data, uint32_t length) set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length)); set_friend_userstatus(m, fnum, temp.userstatus); - uint8_t lastonline[sizeof(uint64_t)]; - memcpy(lastonline, &temp.ping_lastrecv, sizeof(uint64_t)); - net_to_host(lastonline, sizeof(uint64_t)); - memcpy(&m->friendlist[fnum].ping_lastrecv, lastonline, sizeof(uint64_t)); + if (!old_data) { + uint8_t lastonline[sizeof(uint64_t)]; + memcpy(lastonline, &temp.ping_lastrecv, sizeof(uint64_t)); + net_to_host(lastonline, sizeof(uint64_t)); + memcpy(&m->friendlist[fnum].ping_lastrecv, lastonline, sizeof(uint64_t)); + } } else if (temp.status != 0) { /* TODO: This is not a good way to do this. */ uint8_t address[FRIEND_ADDRESS_SIZE];