From 6d31a9be7ecf486793ba4eb4296eb08429071a7d Mon Sep 17 00:00:00 2001 From: "Coren[m]" Date: Tue, 12 Nov 2013 19:56:32 +0100 Subject: [PATCH] Group chat: Add a nickname message. Remove strange default nickname. (Seriously...) group_chats.*: - group_send_nick() to send own name - setnick() to store a received name Messenger.c: - group_send_nick() before group_sendmessage() (in regular intervals, to inform new peers) nTox.c: - print_groupmessage(): on error or on a name of length zero the result of tox_group_peername() isn't null-terminated, catch that --- testing/nTox.c | 12 +++++++-- toxcore/Messenger.c | 14 +++++++++++ toxcore/group_chats.c | 57 +++++++++++++++++++++++++++++++++++++++---- toxcore/group_chats.h | 9 +++++++ 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/testing/nTox.c b/testing/nTox.c index 22756957..9a6614c0 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -821,8 +821,16 @@ void print_groupmessage(Tox *m, int groupnumber, int peernumber, uint8_t *messag { char msg[256 + length]; uint8_t name[TOX_MAX_NAME_LENGTH]; - tox_group_peername(m, groupnumber, peernumber, name); - sprintf(msg, "[g] %u: <%s>: %s", groupnumber, name, message); + int len = tox_group_peername(m, groupnumber, peernumber, name); + + if (len <= 0) + name[0] = 0; + + if (name[0] != 0) + sprintf(msg, "[g] %u: %u <%s>: %s", groupnumber, peernumber, name, message); + else + sprintf(msg, "[g] %u: %u Unknown: %s", groupnumber, peernumber, message); + new_lines(msg); } diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 659c837b..12c59cb3 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -435,6 +435,9 @@ int setname(Messenger *m, uint8_t *name, uint16_t length) for (i = 0; i < m->numfriends; ++i) m->friendlist[i].name_sent = 0; + for (i = 0; i < m->numchats; i++) + m->chats[i]->last_sent_nick = 0; /* or send the new name right away? */ + return 0; } @@ -969,6 +972,17 @@ int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t if (m->chats[groupnumber] == NULL) return -1; + /* send own nick from time to time, to let newly added peers be informed + * first time only: use a shorter timeframe, because we might not be in our own + * peer list yet */ + if (is_timeout(m->chats[groupnumber]->last_sent_nick, 180)) + if (group_send_nick(m->chats[groupnumber], m->chats[groupnumber]->self_public_key, m->name, m->name_length) > 0) { + if (!m->chats[groupnumber]->last_sent_nick) + m->chats[groupnumber]->last_sent_nick = unix_time() - 150; + else + m->chats[groupnumber]->last_sent_nick = unix_time(); + } + if (group_sendmessage(m->chats[groupnumber], message, length) > 0) return 0; diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 9275d63e..60026eed 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -53,6 +53,11 @@ typedef struct { } sendnodes_data; +typedef struct { + uint8_t client_id[crypto_box_PUBLICKEYBYTES]; + uint8_t nickname[MAX_NICK_BYTES]; +} peernick_data; + /* * check if peer with client_id is in peer array. @@ -211,10 +216,12 @@ static int addpeer(Group_Chat *chat, uint8_t *client_id) memset(&(temp[chat->numpeers]), 0, sizeof(Group_Peer)); chat->group = temp; + id_copy(chat->group[chat->numpeers].client_id, client_id); chat->group[chat->numpeers].last_recv = unix_time(); chat->group[chat->numpeers].last_recv_msgping = unix_time(); ++chat->numpeers; + return (chat->numpeers - 1); } @@ -262,14 +269,34 @@ int group_peername(Group_Chat *chat, int peernum, uint8_t *name) return -1; if (chat->group[peernum].nick_len == 0) { - memcpy(name, "NSA Agent", 10); /* Kindly remind the user that someone with no name might be an NSA agent.*/ - return 10; + /* memcpy(name, "NSA agent", 10); */ /* Srsly? */ /* Kindly remind the user that someone with no name might be a moronic NSA agent.*/ + name[0] = 0; + return 0; } memcpy(name, chat->group[peernum].nick, chat->group[peernum].nick_len); return chat->group[peernum].nick_len; } +static void setnick(Group_Chat *chat, uint8_t *contents, uint16_t contents_len) +{ + if (contents_len > CLIENT_ID_SIZE + MAX_NICK_BYTES) + return; + + peernick_data *data = (peernick_data *)contents; + + size_t i; + + for (i = 0; i < chat->numpeers; i++) + if (id_equal(chat->group[i].client_id, data->client_id)) { + uint16_t nick_len = contents_len - CLIENT_ID_SIZE; + + memcpy(chat->group[i].nick, data->nickname, nick_len); + chat->group[i].nick_len = nick_len; + + return; + } +} /* min time between pings sent to one peer in seconds */ /* TODO: move this to global section */ @@ -289,7 +316,8 @@ static int send_getnodes(Group_Chat *chat, IP_Port ip_port, int peernum) chat->group[peernum].last_pinged = unix_time(); chat->group[peernum].pingid = contents.pingid; - return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), CRYPTO_PACKET_GROUP_CHAT_GET_NODES); + return send_groupchatpacket(chat, ip_port, chat->group[peernum].client_id, (uint8_t *)&contents, sizeof(contents), + CRYPTO_PACKET_GROUP_CHAT_GET_NODES); } static int send_sendnodes(Group_Chat *chat, IP_Port ip_port, int peernum, uint64_t pingid) @@ -428,6 +456,13 @@ static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len) addpeer(chat, contents); break; + case GROUP_CHAT_PEER_NICK: + if (contents_len < crypto_box_PUBLICKEYBYTES) + return 1; + + setnick(chat, contents, contents_len); + break; + case GROUP_CHAT_CHAT_MESSAGE: /* If message is chat message */ if (chat->group_message != NULL) (*chat->group_message)(chat, peernum, contents, contents_len, chat->group_message_userdata); @@ -520,6 +555,18 @@ uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length) return send_data(chat, message, length, GROUP_CHAT_CHAT_MESSAGE); //TODO: better return values? } +uint32_t group_send_nick(Group_Chat *chat, uint8_t *client_id, uint8_t *nick, uint16_t nick_len) +{ + peernick_data peernick; + id_copy(peernick.client_id, client_id); + memcpy(peernick.nickname, nick, nick_len); + + /* also set for self */ + setnick(chat, (uint8_t *)&peernick, sizeof(peernick.client_id) + nick_len); + + return send_data(chat, (uint8_t *)&peernick, sizeof(peernick.client_id) + nick_len, GROUP_CHAT_PEER_NICK); +} + uint32_t group_newpeer(Group_Chat *chat, uint8_t *client_id) { addpeer(chat, client_id); @@ -553,7 +600,6 @@ static void ping_close(Group_Chat *chat) uint32_t i; for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { - /* previous condition was always true, assuming this is the wanted one: */ if (!is_timeout(chat->close[i].last_recv, BAD_GROUPNODE_TIMEOUT)) { int peernum = peer_in_chat(chat, chat->close[i].client_id); @@ -580,8 +626,9 @@ static void ping_group(Group_Chat *chat) static void del_dead_peers(Group_Chat *chat) { uint32_t i; + for (i = 0; i < chat->numpeers; ++i) { - if (is_timeout(chat->group[i].last_recv_msgping, GROUP_PING_INTERVAL*2)) { + if (is_timeout(chat->group[i].last_recv_msgping, GROUP_PING_INTERVAL * 2)) { delpeer(chat, chat->group[i].client_id); } } diff --git a/toxcore/group_chats.h b/toxcore/group_chats.h index b3f2e5a8..66fb641f 100644 --- a/toxcore/group_chats.h +++ b/toxcore/group_chats.h @@ -63,12 +63,15 @@ typedef struct Group_Chat { uint32_t message_number; void (*group_message)(struct Group_Chat *m, int, uint8_t *, uint16_t, void *); void *group_message_userdata; + uint64_t last_sent_ping; + uint64_t last_sent_nick; } Group_Chat; #define GROUP_CHAT_PING 0 #define GROUP_CHAT_NEW_PEER 16 +#define GROUP_CHAT_PEER_NICK 17 #define GROUP_CHAT_CHAT_MESSAGE 64 /* Copy the name of peernum to name. @@ -95,6 +98,12 @@ void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat, */ uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length); +/* + * Send id/nick combo to the group. + * + * returns the number of peers it has sent it to. + */ +uint32_t group_send_nick(Group_Chat *chat, uint8_t *client_id, uint8_t *nick, uint16_t nick_len); /* * Tell everyone about a new peer (a person we are inviting for example.)