#include "conf.h"
extern channel_t *defaultChan;
+extern int iCodecAlpha, iCodecBeta;
+extern bool_t bPreferAlpha;
static void sendServerReject(client_t *client, const char *reason, MumbleProto__Reject__RejectType type)
{
while (Client_iterate(&client_itr) != NULL) {
if (!IS_AUTH(client_itr))
continue;
- if (strncmp(client_itr->playerName, msg->payload.authenticate->username, MAX_TEXT) == 0) {
+ if (client_itr->playerName && strncmp(client_itr->playerName, msg->payload.authenticate->username, MAX_TEXT) == 0) {
char buf[64];
sprintf(buf, "Username already in use");
Log_debug("Username already in use");
}
/* Name & password */
- strncpy(client->playerName, msg->payload.authenticate->username, MAX_TEXT);
- client->playerId = client->sessionId;
-
-
- /* XXX - Kick ghost? */
+ client->playerName = strdup(msg->payload.authenticate->username);
/* Setup UDP encryption */
CryptState_init(&client->cryptState);
/* Channel stuff */
Chan_playerJoin(defaultChan, client); /* Join default channel */
+ /* Codec version */
+ if (msg->payload.authenticate->n_celt_versions > MAX_CODECS)
+ Log_warn("Client has more than %d CELT codecs. Ignoring %d codecs",
+ MAX_CODECS, msg->payload.authenticate->n_celt_versions - MAX_CODECS);
+
+ Log_debug("Client %d has %d CELT codecs", client->sessionId, msg->payload.authenticate->n_celt_versions);
+ if (msg->payload.authenticate->n_celt_versions > 0) {
+ int i;
+ client->codec_count = msg->payload.authenticate->n_celt_versions > MAX_CODECS ?
+ MAX_CODECS : msg->payload.authenticate->n_celt_versions;
+ for (i = 0; i < client->codec_count; i++) {
+ client->codecs[i] = msg->payload.authenticate->celt_versions[i];
+ Log_debug("Client %d CELT codec ver 0x%x", client->sessionId, client->codecs[i]);
+ }
+ } else {
+ client->codecs[0] = (int32_t)0x8000000a;
+ client->codec_count = 1;
+ }
+
+ recheckCodecVersions();
+
+ sendmsg = Msg_create(CodecVersion);
+ sendmsg->payload.codecVersion->alpha = iCodecAlpha;
+ sendmsg->payload.codecVersion->beta = iCodecBeta;
+ sendmsg->payload.codecVersion->prefer_alpha = bPreferAlpha;
+ Client_send_message(client, sendmsg);
+
/* Iterate channels and send channel info */
ch_itr = NULL;
Chan_iterate(&ch_itr);
sendmsg->payload.userState->has_session = true;
sendmsg->payload.userState->session = client->sessionId;
sendmsg->payload.userState->has_user_id = true;
- sendmsg->payload.userState->user_id = client->playerId;
+ sendmsg->payload.userState->user_id = client->sessionId;
sendmsg->payload.userState->name = strdup(client->playerName);
sendmsg->payload.userState->has_channel_id = true;
sendmsg->payload.userState->channel_id = ((channel_t *)client->channel)->id;
continue;
sendmsg = Msg_create(UserState);
sendmsg->payload.userState->has_session = true;
- sendmsg->payload.userState->session = client->sessionId;
- sendmsg->payload.userState->name = strdup(client->playerName);
+ sendmsg->payload.userState->session = client_itr->sessionId;
+ sendmsg->payload.userState->name = strdup(client_itr->playerName);
sendmsg->payload.userState->has_channel_id = true;
- sendmsg->payload.userState->channel_id = ((channel_t *)client->channel)->id;
+ sendmsg->payload.userState->channel_id = ((channel_t *)client_itr->channel)->id;
/* XXX - check if self_* is correct */
- if (client->deaf) {
+ if (client_itr->deaf) {
sendmsg->payload.userState->has_self_deaf = true;
sendmsg->payload.userState->self_deaf = true;
}
- if (client->mute) {
+ if (client_itr->mute) {
sendmsg->payload.userState->has_self_mute = true;
sendmsg->payload.userState->self_mute = true;
}
sendmsg->payload.serverSync->has_max_bandwidth = true;
sendmsg->payload.serverSync->max_bandwidth = getIntConf(MAX_BANDWIDTH);
sendmsg->payload.serverSync->has_allow_html = true;
- sendmsg->payload.serverSync->allow_html = false; /* Support this? */
+ sendmsg->payload.serverSync->allow_html = true; /* Support this? */
Client_send_message(client, sendmsg);
Log_info("User %s authenticated", client->playerName);
break;
case Ping:
- {
- uint64_t timestamp;
if (msg->payload.ping->has_good)
client->cryptState.uiRemoteGood = msg->payload.ping->good;
if (msg->payload.ping->has_late)
/* Ignoring the double values since they don't seem to be used */
sendmsg = Msg_create(Ping);
- timestamp = msg->payload.ping->timestamp;
- sendmsg->payload.ping->timestamp = timestamp;
-
+ sendmsg->payload.ping->timestamp = msg->payload.ping->timestamp;
+ sendmsg->payload.ping->has_timestamp = true;
sendmsg->payload.ping->good = client->cryptState.uiGood;
sendmsg->payload.ping->has_good = true;
sendmsg->payload.ping->late = client->cryptState.uiLate;
client->cryptState.uiLost, client->cryptState.uiResync);
break;
- }
case CryptSetup:
Log_debug("Voice channel crypt resync requested");
if (!msg->payload.cryptSetup->has_client_nonce) {
sendmsg = Msg_create(CryptSetup);
sendmsg->payload.cryptSetup->has_server_nonce = true;
- memcpy(sendmsg->payload.cryptSetup->server_nonce.data, client->cryptState.decrypt_iv, AES_BLOCK_SIZE);
+ sendmsg->payload.cryptSetup->server_nonce.data = client->cryptState.decrypt_iv;
sendmsg->payload.cryptSetup->server_nonce.len = AES_BLOCK_SIZE;
Client_send_message(client, sendmsg);
} else {
break;
case TextMessage:
-#if 0
- if (msg->payload.textMessage.bTree)
+ msg->payload.textMessage->has_actor = true;
+ msg->payload.textMessage->actor = client->sessionId;
+
+ /* XXX - Allow HTML stuff? */
+
+ if (msg->payload.textMessage->n_tree_id > 0) {
sendPermissionDenied(client, "Tree message not supported");
- else if (msg->payload.textMessage.channel != -1) { /* To channel */
- channel_t *ch_itr = NULL;
- do {
- Chan_iterate(&ch_itr);
- } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage.channel);
- if (ch_itr == NULL)
- Log_warn("Channel id %d not found - ignoring.", msg->payload.textMessage.channel);
- else {
- struct dlist *itr;
- list_iterate(itr, &ch_itr->clients) {
- client_t *c;
- c = list_get_entry(itr, client_t, chan_node);
- if (c != client && !c->deaf) {
- Msg_inc_ref(msg);
- Client_send_message(c, msg);
- Log_debug("Text message to player ID %d", c->playerId);
+ break;
+ }
+
+ if (msg->payload.textMessage->n_channel_id > 0) { /* To channel */
+ int i;
+ channel_t *ch_itr;
+ for (i = 0; i < msg->payload.textMessage->n_channel_id; i++) {
+ ch_itr = NULL;
+ do {
+ Chan_iterate(&ch_itr);
+ } while (ch_itr != NULL && ch_itr->id != msg->payload.textMessage->channel_id[i]);
+ if (ch_itr == NULL)
+ Log_warn("Channel id %d not found - ignoring.", msg->payload.textMessage->channel_id[i]);
+ else {
+ struct dlist *itr;
+ list_iterate(itr, &ch_itr->clients) {
+ client_t *c;
+ c = list_get_entry(itr, client_t, chan_node);
+ if (c != client && !c->deaf) {
+ Msg_inc_ref(msg);
+ Client_send_message(c, msg);
+ Log_debug("Text message to session ID %d", c->sessionId);
+ }
}
}
- }
- } else { /* To player */
- client_t *itr = NULL;
- while (Client_iterate(&itr) != NULL) {
- if (!IS_AUTH(itr))
- continue;
- if (itr->playerId == msg->payload.textMessage.victim) {
- if (!itr->deaf) {
- Msg_inc_ref(msg);
- Client_send_message(itr, msg);
+ } /* for */
+ }
+ if (msg->payload.textMessage->n_session > 0) { /* To user */
+ int i;
+ client_t *itr;
+ for (i = 0; i < msg->payload.textMessage->n_session; i++) {
+ itr = NULL;
+ while (Client_iterate(&itr) != NULL) {
+ if (!IS_AUTH(itr))
+ continue;
+ if (itr->sessionId == msg->payload.textMessage->session[i]) {
+ if (!itr->deaf) {
+ Msg_inc_ref(msg);
+ Client_send_message(itr, msg);
+ Log_debug("Text message to session ID %d", itr->sessionId);
+ }
+ break;
}
- break;
}
- }
- if (itr == NULL)
- Log_warn("TextMessage: Player ID %d not found", msg->payload.textMessage.victim);
+ if (itr == NULL)
+ Log_warn("TextMessage: Session ID %d not found", msg->payload.textMessage->session[i]);
+ } /* for */
}
break;
-#endif
case VoiceTarget:
/* XXX -TODO */
break;
case Version:
- sendmsg = Msg_create(Version); /* Re-use message */
Log_debug("Version message received");
- sendmsg->payload.version->has_version = true;
- sendmsg->payload.version->version = (1 << 16) | (2 << 8) | 0; /* XXX fix */
- sendmsg->payload.version->release = "Phony donkey";
- sendmsg->payload.version->os = "OpenWRT";
-
- Client_send_message(client, sendmsg);
+ if (msg->payload.version->has_version) {
+ client->version = msg->payload.version->version;
+ Log_debug("Client version 0x%x", client->version);
+ }
+ if (msg->payload.version->release) {
+ if (client->release) free(client->release);
+ client->release = strdup(msg->payload.version->release);
+ Log_debug("Client release %s", client->release);
+ }
+ if (msg->payload.version->os) {
+ if (client->os) free(client->os);
+ client->os = strdup(msg->payload.version->os);
+ Log_debug("Client OS %s", client->os);
+ }
break;
- case CodecVersion:
+ case PermissionQuery:
Msg_inc_ref(msg); /* Re-use message */
-
- /* XXX - fill in version */
+ msg->payload.permissionQuery->has_permissions = true;
+ msg->payload.permissionQuery->permissions = PERM_DEFAULT;
Client_send_message(client, msg);
break;
Msg_free(msg);
Client_close(client);
}
+