From: fatbob313 Date: Mon, 6 Dec 2010 20:03:03 +0000 (+0000) Subject: Add functions for sending messages to clients with different Mumble versions. X-Git-Url: http://git.code-monkey.de/?p=umurmur.git;a=commitdiff_plain;h=082533e47427c10c255a12a962b8d8ea7ef0bdc0 Add functions for sending messages to clients with different Mumble versions. Add recording support. --- diff --git a/src/client.c b/src/client.c index 963ec4d..35ab266 100644 --- a/src/client.c +++ b/src/client.c @@ -505,6 +505,15 @@ int Client_write(client_t *client) return 0; } +int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version) +{ + if ((version == 0) || (client->version >= version) || + ((version & 0x80000000) && (client->version < (~version)))) + return Client_send_message(client, msg); + else + Msg_free(msg); +} + int Client_send_message(client_t *client, message_t *msg) { if (!client->authenticated && msg->messageType != Version) { @@ -577,6 +586,29 @@ int Client_send_message_except(client_t *client, message_t *msg) return 0; } +int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version) +{ + client_t *itr = NULL; + int count = 0; + + Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */ + while (Client_iterate(&itr) != NULL) { + if (itr != client) { + if (count++ > 0) + Msg_inc_ref(msg); /* One extra reference for each new copy */ + Log_debug("Msg %d to %s refcount %d", msg->messageType, itr->username, msg->refcount); + Client_send_message_ver(itr, msg, version); + } + } + Msg_free(msg); /* Free our reference to the message */ + + if (count == 0) + Msg_free(msg); /* If only 1 client is connected then no message is passed + * to Client_send_message(). Free it here. */ + + return 0; +} + static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len) { if (CryptState_isValid(&client->cryptState) && diff --git a/src/client.h b/src/client.h index d2f935c..a74a206 100644 --- a/src/client.h +++ b/src/client.h @@ -70,7 +70,7 @@ typedef struct { int sessionId; uint64_t key; char *username; - bool_t bUDP, authenticated, deaf, mute; + bool_t bUDP, authenticated, deaf, mute, recording; char *os, *release, *os_version; uint32_t version; int codec_count; @@ -100,6 +100,8 @@ int Client_add(int fd, struct sockaddr_in *remote); int Client_read_fd(int fd); int Client_write_fd(int fd); int Client_send_message(client_t *client, message_t *msg); +int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version); +int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version); int Client_count(void); void Client_close(client_t *client); client_t *Client_iterate(client_t **client); diff --git a/src/messagehandler.c b/src/messagehandler.c index 640a736..c2aa522 100644 --- a/src/messagehandler.c +++ b/src/messagehandler.c @@ -42,6 +42,7 @@ #include "voicetarget.h" #define MAX_TEXT 512 +#define MAX_USERNAME 128 extern channel_t *defaultChan; extern int iCodecAlpha, iCodecBeta; @@ -108,7 +109,7 @@ void Mh_handle_message(client_t *client, message_t *msg) while (Client_iterate(&client_itr) != NULL) { if (!IS_AUTH(client_itr)) continue; - if (client_itr->username && strncmp(client_itr->username, msg->payload.authenticate->username, MAX_TEXT) == 0) { + if (client_itr->username && strncmp(client_itr->username, msg->payload.authenticate->username, MAX_USERNAME) == 0) { char buf[64]; sprintf(buf, "Username already in use"); Log_debug("Username already in use"); @@ -129,7 +130,7 @@ void Mh_handle_message(client_t *client, message_t *msg) } } if (strlen(msg->payload.authenticate->username) == 0 || - strlen(msg->payload.authenticate->username) >= MAX_TEXT) { /* XXX - other invalid names? */ + strlen(msg->payload.authenticate->username) >= MAX_USERNAME) { /* XXX - other invalid names? */ char buf[64]; sprintf(buf, "Invalid username"); Log_debug("Invalid username"); @@ -240,7 +241,7 @@ void Mh_handle_message(client_t *client, message_t *msg) sendmsg->payload.userState->name = strdup(client->username); sendmsg->payload.userState->has_channel_id = true; sendmsg->payload.userState->channel_id = ((channel_t *)client->channel)->id; - + Client_send_message_except(client, sendmsg); client_itr = NULL; @@ -263,6 +264,10 @@ void Mh_handle_message(client_t *client, message_t *msg) sendmsg->payload.userState->has_self_mute = true; sendmsg->payload.userState->self_mute = true; } + if (client_itr->recording) { + sendmsg->payload.userState->has_recording = true; + sendmsg->payload.userState->recording = true; + } Client_send_message(client, sendmsg); } @@ -373,6 +378,30 @@ void Mh_handle_message(client_t *client, message_t *msg) client->deaf = false; } } + if (msg->payload.userState->has_recording && + msg->payload.userState->recording != client->recording) { + client->recording = msg->payload.userState->recording; + char *message; + uint32_t *tree_id; + + message = malloc(strlen(client->username) + 32); + if (!message) + Log_fatal("Out of memory"); + tree_id = malloc(sizeof(uint32_t)); + if (!tree_id) + Log_fatal("Out of memory"); + *tree_id = 0; + sendmsg = Msg_create(TextMessage); + sendmsg->payload.textMessage->message = message; + sendmsg->payload.textMessage->n_tree_id = 1; + sendmsg->payload.textMessage->tree_id = tree_id; + if (client->recording) + sprintf(message, "User %s started recording", client->username); + else + sprintf(message, "User %s stopped recording", client->username); + Client_send_message_except_ver(NULL, sendmsg, ~0x010203); + sendmsg = NULL; + } if (msg->payload.userState->has_channel_id) { int leave_id; if (!Chan_userJoin_id_test(msg->payload.userState->channel_id)) @@ -395,7 +424,6 @@ void Mh_handle_message(client_t *client, message_t *msg) break; /* Don't inform other users about this state */ } - /* Re-use message */ Msg_inc_ref(msg); diff --git a/src/messages.c b/src/messages.c index 5a61082..38d4ea9 100644 --- a/src/messages.c +++ b/src/messages.c @@ -436,6 +436,14 @@ void Msg_free(message_t *msg) if (msg->unpacked) mumble_proto__text_message__free_unpacked(msg->payload.textMessage, NULL); else { + if (msg->payload.textMessage->message) + free(msg->payload.textMessage->message); + if (msg->payload.textMessage->session) + free(msg->payload.textMessage->session); + if (msg->payload.textMessage->channel_id) + free(msg->payload.textMessage->channel_id); + if (msg->payload.textMessage->tree_id) + free(msg->payload.textMessage->tree_id); free(msg->payload.textMessage); } break;