diff options
Diffstat (limited to 'linden/indra/newview/llvoiceclient.cpp')
-rw-r--r-- | linden/indra/newview/llvoiceclient.cpp | 218 |
1 files changed, 150 insertions, 68 deletions
diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp index 7f63aca..64a17ae 100644 --- a/linden/indra/newview/llvoiceclient.cpp +++ b/linden/indra/newview/llvoiceclient.cpp | |||
@@ -1,4 +1,4 @@ | |||
1 | /** | 1 | /** |
2 | * @file llvoiceclient.cpp | 2 | * @file llvoiceclient.cpp |
3 | * @brief Implementation of LLVoiceClient class which is the interface to the voice client process. | 3 | * @brief Implementation of LLVoiceClient class which is the interface to the voice client process. |
4 | * | 4 | * |
@@ -39,7 +39,11 @@ | |||
39 | #include "llvoavatar.h" | 39 | #include "llvoavatar.h" |
40 | #include "llbufferstream.h" | 40 | #include "llbufferstream.h" |
41 | #include "llfile.h" | 41 | #include "llfile.h" |
42 | #include "expat/expat.h" | 42 | #ifdef LL_STANDALONE |
43 | # include "expat.h" | ||
44 | #else | ||
45 | # include "expat/expat.h" | ||
46 | #endif | ||
43 | #include "llcallbacklist.h" | 47 | #include "llcallbacklist.h" |
44 | #include "llviewerregion.h" | 48 | #include "llviewerregion.h" |
45 | #include "llviewernetwork.h" // for gGridChoice | 49 | #include "llviewernetwork.h" // for gGridChoice |
@@ -56,12 +60,13 @@ | |||
56 | #include "llviewerparcelmgr.h" | 60 | #include "llviewerparcelmgr.h" |
57 | #include "llfirstuse.h" | 61 | #include "llfirstuse.h" |
58 | #include "llviewerwindow.h" | 62 | #include "llviewerwindow.h" |
63 | #include "llviewercamera.h" | ||
59 | 64 | ||
60 | // for base64 decoding | 65 | // for base64 decoding |
61 | #include "apr-1/apr_base64.h" | 66 | #include "apr_base64.h" |
62 | 67 | ||
63 | // for SHA1 hash | 68 | // for SHA1 hash |
64 | #include "apr-1/apr_sha1.h" | 69 | #include "apr_sha1.h" |
65 | 70 | ||
66 | // If we are connecting to agni AND the user's last name is "Linden", join this channel instead of looking up the sim name. | 71 | // If we are connecting to agni AND the user's last name is "Linden", join this channel instead of looking up the sim name. |
67 | // If we are connecting to agni and the user's last name is NOT "Linden", disable voice. | 72 | // If we are connecting to agni and the user's last name is NOT "Linden", disable voice. |
@@ -218,6 +223,19 @@ void LLVivoxProtocolParser::reset() | |||
218 | ignoringTags = false; | 223 | ignoringTags = false; |
219 | accumulateText = false; | 224 | accumulateText = false; |
220 | textBuffer.clear(); | 225 | textBuffer.clear(); |
226 | |||
227 | energy = 0.f; | ||
228 | ignoreDepth = 0; | ||
229 | isChannel = false; | ||
230 | isEvent = false; | ||
231 | isLocallyMuted = false; | ||
232 | isModeratorMuted = false; | ||
233 | isSpeaking = false; | ||
234 | participantType = 0; | ||
235 | returnCode = 0; | ||
236 | state = 0; | ||
237 | statusCode = 0; | ||
238 | volume = 0; | ||
221 | } | 239 | } |
222 | 240 | ||
223 | //virtual | 241 | //virtual |
@@ -404,7 +422,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) | |||
404 | 422 | ||
405 | void LLVivoxProtocolParser::EndTag(const char *tag) | 423 | void LLVivoxProtocolParser::EndTag(const char *tag) |
406 | { | 424 | { |
407 | const char *string = textBuffer.c_str(); | 425 | const std::string& string = textBuffer; |
408 | bool clearbuffer = true; | 426 | bool clearbuffer = true; |
409 | 427 | ||
410 | responseDepth--; | 428 | responseDepth--; |
@@ -428,9 +446,9 @@ void LLVivoxProtocolParser::EndTag(const char *tag) | |||
428 | 446 | ||
429 | // Closing a tag. Finalize the text we've accumulated and reset | 447 | // Closing a tag. Finalize the text we've accumulated and reset |
430 | if (strcmp("ReturnCode", tag) == 0) | 448 | if (strcmp("ReturnCode", tag) == 0) |
431 | returnCode = strtol(string, NULL, 10); | 449 | returnCode = strtol(string.c_str(), NULL, 10); |
432 | else if (strcmp("StatusCode", tag) == 0) | 450 | else if (strcmp("StatusCode", tag) == 0) |
433 | statusCode = strtol(string, NULL, 10); | 451 | statusCode = strtol(string.c_str(), NULL, 10); |
434 | else if (strcmp("ConnectorHandle", tag) == 0) | 452 | else if (strcmp("ConnectorHandle", tag) == 0) |
435 | connectorHandle = string; | 453 | connectorHandle = string; |
436 | else if (strcmp("AccountHandle", tag) == 0) | 454 | else if (strcmp("AccountHandle", tag) == 0) |
@@ -445,11 +463,11 @@ void LLVivoxProtocolParser::EndTag(const char *tag) | |||
445 | else if (strcmp("StatusString", tag) == 0) | 463 | else if (strcmp("StatusString", tag) == 0) |
446 | statusString = string; | 464 | statusString = string; |
447 | else if (strcmp("State", tag) == 0) | 465 | else if (strcmp("State", tag) == 0) |
448 | state = strtol(string, NULL, 10); | 466 | state = strtol(string.c_str(), NULL, 10); |
449 | else if (strcmp("URI", tag) == 0) | 467 | else if (strcmp("URI", tag) == 0) |
450 | uriString = string; | 468 | uriString = string; |
451 | else if (strcmp("IsChannel", tag) == 0) | 469 | else if (strcmp("IsChannel", tag) == 0) |
452 | isChannel = strcmp(string, "true") == 0; | 470 | isChannel = string == "true" ? true : false; |
453 | else if (strcmp("Name", tag) == 0) | 471 | else if (strcmp("Name", tag) == 0) |
454 | nameString = string; | 472 | nameString = string; |
455 | else if (strcmp("AudioMedia", tag) == 0) | 473 | else if (strcmp("AudioMedia", tag) == 0) |
@@ -463,19 +481,19 @@ void LLVivoxProtocolParser::EndTag(const char *tag) | |||
463 | else if (strcmp("AccountName", tag) == 0) | 481 | else if (strcmp("AccountName", tag) == 0) |
464 | nameString = string; | 482 | nameString = string; |
465 | else if (strcmp("ParticipantTyppe", tag) == 0) | 483 | else if (strcmp("ParticipantTyppe", tag) == 0) |
466 | participantType = strtol(string, NULL, 10); | 484 | participantType = strtol(string.c_str(), NULL, 10); |
467 | else if (strcmp("IsLocallyMuted", tag) == 0) | 485 | else if (strcmp("IsLocallyMuted", tag) == 0) |
468 | isLocallyMuted = strcmp(string, "true") == 0; | 486 | isLocallyMuted = string == "true" ? true : false; |
469 | else if (strcmp("IsModeratorMuted", tag) == 0) | 487 | else if (strcmp("IsModeratorMuted", tag) == 0) |
470 | isModeratorMuted = strcmp(string, "true") == 0; | 488 | isModeratorMuted = string == "true" ? true : false; |
471 | else if (strcmp("IsSpeaking", tag) == 0) | 489 | else if (strcmp("IsSpeaking", tag) == 0) |
472 | isSpeaking = strcmp(string, "true") == 0; | 490 | isSpeaking = string == "true" ? true : false; |
473 | else if (strcmp("Volume", tag) == 0) | 491 | else if (strcmp("Volume", tag) == 0) |
474 | volume = strtol(string, NULL, 10); | 492 | volume = strtol(string.c_str(), NULL, 10); |
475 | else if (strcmp("Energy", tag) == 0) | 493 | else if (strcmp("Energy", tag) == 0) |
476 | energy = (F32)strtod(string, NULL); | 494 | energy = (F32)strtod(string.c_str(), NULL); |
477 | else if (strcmp("MicEnergy", tag) == 0) | 495 | else if (strcmp("MicEnergy", tag) == 0) |
478 | energy = (F32)strtod(string, NULL); | 496 | energy = (F32)strtod(string.c_str(), NULL); |
479 | else if (strcmp("ChannelName", tag) == 0) | 497 | else if (strcmp("ChannelName", tag) == 0) |
480 | nameString = string; | 498 | nameString = string; |
481 | else if (strcmp("ChannelURI", tag) == 0) | 499 | else if (strcmp("ChannelURI", tag) == 0) |
@@ -821,19 +839,12 @@ LLVoiceClient::LLVoiceClient() | |||
821 | mCaptureDeviceDirty = false; | 839 | mCaptureDeviceDirty = false; |
822 | mRenderDeviceDirty = false; | 840 | mRenderDeviceDirty = false; |
823 | 841 | ||
824 | // Load initial state from prefs. | 842 | // Use default values for everything then call updateSettings() after preferences are loaded |
825 | mVoiceEnabled = gSavedSettings.getBOOL("EnableVoiceChat"); | 843 | mVoiceEnabled = false; |
826 | mUsePTT = TRUE; //gSavedSettings.getBOOL("EnablePushToTalk"); | 844 | mUsePTT = true; |
827 | std::string keyString = gSavedSettings.getString("PushToTalkButton"); | 845 | mPTTIsToggle = false; |
828 | setPTTKey(keyString); | 846 | mEarLocation = 0; |
829 | mPTTIsToggle = gSavedSettings.getBOOL("PushToTalkToggle"); | 847 | mLipSyncEnabled = false; |
830 | mEarLocation = gSavedSettings.getS32("VoiceEarLocation"); | ||
831 | setVoiceVolume(gSavedSettings.getBOOL("MuteVoice") ? 0.f : gSavedSettings.getF32("AudioLevelVoice")); | ||
832 | std::string captureDevice = gSavedSettings.getString("VoiceInputAudioDevice"); | ||
833 | setCaptureDevice(captureDevice); | ||
834 | std::string renderDevice = gSavedSettings.getString("VoiceOutputAudioDevice"); | ||
835 | setRenderDevice(renderDevice); | ||
836 | mLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled"); | ||
837 | 848 | ||
838 | mTuningMode = false; | 849 | mTuningMode = false; |
839 | mTuningEnergy = 0.0f; | 850 | mTuningEnergy = 0.0f; |
@@ -877,12 +888,11 @@ LLVoiceClient::~LLVoiceClient() | |||
877 | 888 | ||
878 | //---------------------------------------------- | 889 | //---------------------------------------------- |
879 | 890 | ||
880 | |||
881 | |||
882 | void LLVoiceClient::init(LLPumpIO *pump) | 891 | void LLVoiceClient::init(LLPumpIO *pump) |
883 | { | 892 | { |
884 | // constructor will set up gVoiceClient | 893 | // constructor will set up gVoiceClient |
885 | LLVoiceClient::getInstance()->mPump = pump; | 894 | LLVoiceClient::getInstance()->mPump = pump; |
895 | LLVoiceClient::getInstance()->updateSettings(); | ||
886 | } | 896 | } |
887 | 897 | ||
888 | void LLVoiceClient::terminate() | 898 | void LLVoiceClient::terminate() |
@@ -905,6 +915,25 @@ void LLVoiceClient::terminate() | |||
905 | } | 915 | } |
906 | } | 916 | } |
907 | 917 | ||
918 | //--------------------------------------------------- | ||
919 | |||
920 | void LLVoiceClient::updateSettings() | ||
921 | { | ||
922 | setVoiceEnabled(gSavedSettings.getBOOL("EnableVoiceChat")); | ||
923 | setUsePTT(gSavedSettings.getBOOL("PTTCurrentlyEnabled")); | ||
924 | std::string keyString = gSavedSettings.getString("PushToTalkButton"); | ||
925 | setPTTKey(keyString); | ||
926 | setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle")); | ||
927 | setEarLocation(gSavedSettings.getS32("VoiceEarLocation")); | ||
928 | std::string serverName = gSavedSettings.getString("VivoxDebugServerName"); | ||
929 | setVivoxDebugServerName(serverName); | ||
930 | |||
931 | std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice"); | ||
932 | setCaptureDevice(inputDevice); | ||
933 | std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice"); | ||
934 | setRenderDevice(outputDevice); | ||
935 | setLipSyncEnabled(gSavedSettings.getBOOL("LipSyncEnabled")); | ||
936 | } | ||
908 | 937 | ||
909 | ///////////////////////////// | 938 | ///////////////////////////// |
910 | // utility functions | 939 | // utility functions |
@@ -1079,9 +1108,9 @@ void LLVoiceClient::idle(void* user_data) | |||
1079 | self->stateMachine(); | 1108 | self->stateMachine(); |
1080 | } | 1109 | } |
1081 | 1110 | ||
1082 | const char *LLVoiceClient::state2string(LLVoiceClient::state inState) | 1111 | std::string LLVoiceClient::state2string(LLVoiceClient::state inState) |
1083 | { | 1112 | { |
1084 | const char *result = "UNKNOWN"; | 1113 | std::string result = "UNKNOWN"; |
1085 | 1114 | ||
1086 | // Prevent copy-paste errors when updating this list... | 1115 | // Prevent copy-paste errors when updating this list... |
1087 | #define CASE(x) case x: result = #x; break | 1116 | #define CASE(x) case x: result = #x; break |
@@ -1131,9 +1160,9 @@ const char *LLVoiceClient::state2string(LLVoiceClient::state inState) | |||
1131 | return result; | 1160 | return result; |
1132 | } | 1161 | } |
1133 | 1162 | ||
1134 | const char *LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus) | 1163 | std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus) |
1135 | { | 1164 | { |
1136 | const char *result = "UNKNOWN"; | 1165 | std::string result = "UNKNOWN"; |
1137 | 1166 | ||
1138 | // Prevent copy-paste errors when updating this list... | 1167 | // Prevent copy-paste errors when updating this list... |
1139 | #define CASE(x) case x: result = #x; break | 1168 | #define CASE(x) case x: result = #x; break |
@@ -1174,7 +1203,11 @@ void LLVoiceClient::stateMachine() | |||
1174 | setVoiceEnabled(false); | 1203 | setVoiceEnabled(false); |
1175 | } | 1204 | } |
1176 | 1205 | ||
1177 | if(!mVoiceEnabled) | 1206 | if(mVoiceEnabled) |
1207 | { | ||
1208 | updatePosition(); | ||
1209 | } | ||
1210 | else | ||
1178 | { | 1211 | { |
1179 | if(getState() != stateDisabled) | 1212 | if(getState() != stateDisabled) |
1180 | { | 1213 | { |
@@ -1246,17 +1279,23 @@ void LLVoiceClient::stateMachine() | |||
1246 | if(true) | 1279 | if(true) |
1247 | { | 1280 | { |
1248 | // Launch the voice daemon | 1281 | // Launch the voice daemon |
1249 | std::string exe_path = gDirUtilp->getAppRODataDir(); | 1282 | |
1283 | // *FIX:Mani - Using the executable dir instead | ||
1284 | // of mAppRODataDir, the working directory from which the app | ||
1285 | // is launched. | ||
1286 | //std::string exe_path = gDirUtilp->getAppRODataDir(); | ||
1287 | std::string exe_path = gDirUtilp->getExecutableDir(); | ||
1250 | exe_path += gDirUtilp->getDirDelimiter(); | 1288 | exe_path += gDirUtilp->getDirDelimiter(); |
1251 | #if LL_WINDOWS | 1289 | #if LL_WINDOWS |
1252 | exe_path += "SLVoice.exe"; | 1290 | exe_path += "SLVoice.exe"; |
1291 | #elif LL_DARWIN | ||
1292 | exe_path += "../Resources/SLVoice"; | ||
1253 | #else | 1293 | #else |
1254 | // This will be the same for mac and linux | ||
1255 | exe_path += "SLVoice"; | 1294 | exe_path += "SLVoice"; |
1256 | #endif | 1295 | #endif |
1257 | // See if the vivox executable exists | 1296 | // See if the vivox executable exists |
1258 | llstat s; | 1297 | llstat s; |
1259 | if(!LLFile::stat(exe_path.c_str(), &s)) | 1298 | if(!LLFile::stat(exe_path, &s)) |
1260 | { | 1299 | { |
1261 | // vivox executable exists. Build the command line and launch the daemon. | 1300 | // vivox executable exists. Build the command line and launch the daemon. |
1262 | std::string args = " -p tcp -h -c"; | 1301 | std::string args = " -p tcp -h -c"; |
@@ -1302,7 +1341,7 @@ void LLVoiceClient::stateMachine() | |||
1302 | // This should be the same for mac and linux | 1341 | // This should be the same for mac and linux |
1303 | { | 1342 | { |
1304 | std::vector<std::string> arglist; | 1343 | std::vector<std::string> arglist; |
1305 | arglist.push_back(exe_path.c_str()); | 1344 | arglist.push_back(exe_path); |
1306 | 1345 | ||
1307 | // Split the argument string into separate strings for each argument | 1346 | // Split the argument string into separate strings for each argument |
1308 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | 1347 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; |
@@ -1323,6 +1362,7 @@ void LLVoiceClient::stateMachine() | |||
1323 | 1362 | ||
1324 | fakeargv[i] = NULL; | 1363 | fakeargv[i] = NULL; |
1325 | 1364 | ||
1365 | fflush(NULL); // flush all buffers before the child inherits them | ||
1326 | pid_t id = vfork(); | 1366 | pid_t id = vfork(); |
1327 | if(id == 0) | 1367 | if(id == 0) |
1328 | { | 1368 | { |
@@ -1343,7 +1383,7 @@ void LLVoiceClient::stateMachine() | |||
1343 | } | 1383 | } |
1344 | else | 1384 | else |
1345 | { | 1385 | { |
1346 | LL_INFOS("Voice") << exe_path << "not found." << LL_ENDL | 1386 | LL_INFOS("Voice") << exe_path << "not found." << LL_ENDL; |
1347 | } | 1387 | } |
1348 | } | 1388 | } |
1349 | else | 1389 | else |
@@ -1352,7 +1392,7 @@ void LLVoiceClient::stateMachine() | |||
1352 | // To do this, launch the gateway on a nearby host like this: | 1392 | // To do this, launch the gateway on a nearby host like this: |
1353 | // vivox-gw.exe -p tcp -i 0.0.0.0:44124 | 1393 | // vivox-gw.exe -p tcp -i 0.0.0.0:44124 |
1354 | // and put that host's IP address here. | 1394 | // and put that host's IP address here. |
1355 | mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost").c_str(), gSavedSettings.getU32("VoicePort")); | 1395 | mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost"), gSavedSettings.getU32("VoicePort")); |
1356 | } | 1396 | } |
1357 | 1397 | ||
1358 | mUpdateTimer.start(); | 1398 | mUpdateTimer.start(); |
@@ -2903,9 +2943,9 @@ void LLVoiceClient::sessionNewEvent( | |||
2903 | LLIMMgr::computeSessionID( | 2943 | LLIMMgr::computeSessionID( |
2904 | IM_SESSION_P2P_INVITE, | 2944 | IM_SESSION_P2P_INVITE, |
2905 | caller_id), | 2945 | caller_id), |
2906 | LLString::null, | 2946 | LLStringUtil::null, |
2907 | caller_id, | 2947 | caller_id, |
2908 | LLString::null, | 2948 | LLStringUtil::null, |
2909 | IM_SESSION_P2P_INVITE, | 2949 | IM_SESSION_P2P_INVITE, |
2910 | LLIMMgr::INVITATION_TYPE_VOICE, | 2950 | LLIMMgr::INVITATION_TYPE_VOICE, |
2911 | eventSessionHandle); | 2951 | eventSessionHandle); |
@@ -3012,7 +3052,7 @@ void LLVoiceClient::muteListChanged() | |||
3012 | ///////////////////////////// | 3052 | ///////////////////////////// |
3013 | // Managing list of participants | 3053 | // Managing list of participants |
3014 | LLVoiceClient::participantState::participantState(const std::string &uri) : | 3054 | LLVoiceClient::participantState::participantState(const std::string &uri) : |
3015 | mURI(uri), mPTT(false), mIsSpeaking(false), mIsModeratorMuted(false), mPower(0.0), mServiceType(serviceTypeUnknown), | 3055 | mURI(uri), mPTT(false), mIsSpeaking(false), mIsModeratorMuted(false), mLastSpokeTimestamp(0.f), mPower(0.f), mVolume(0), mServiceType(serviceTypeUnknown), |
3016 | mOnMuteList(false), mUserVolume(100), mVolumeDirty(false), mAvatarIDValid(false) | 3056 | mOnMuteList(false), mUserVolume(100), mVolumeDirty(false), mAvatarIDValid(false) |
3017 | { | 3057 | { |
3018 | } | 3058 | } |
@@ -3402,18 +3442,15 @@ std::string LLVoiceClient::nameFromAvatar(LLVOAvatar *avatar) | |||
3402 | std::string LLVoiceClient::nameFromID(const LLUUID &uuid) | 3442 | std::string LLVoiceClient::nameFromID(const LLUUID &uuid) |
3403 | { | 3443 | { |
3404 | std::string result; | 3444 | std::string result; |
3405 | U8 rawuuid[UUID_BYTES + 1]; | ||
3406 | uuid.toCompressedString((char*)rawuuid); | ||
3407 | |||
3408 | // Prepending this apparently prevents conflicts with reserved names inside the vivox and diamondware code. | 3445 | // Prepending this apparently prevents conflicts with reserved names inside the vivox and diamondware code. |
3409 | result = "x"; | 3446 | result = "x"; |
3410 | 3447 | ||
3411 | // Base64 encode and replace the pieces of base64 that are less compatible | 3448 | // Base64 encode and replace the pieces of base64 that are less compatible |
3412 | // with e-mail local-parts. | 3449 | // with e-mail local-parts. |
3413 | // See RFC-4648 "Base 64 Encoding with URL and Filename Safe Alphabet" | 3450 | // See RFC-4648 "Base 64 Encoding with URL and Filename Safe Alphabet" |
3414 | result += LLBase64::encode(rawuuid, UUID_BYTES); | 3451 | result += LLBase64::encode(uuid.mData, UUID_BYTES); |
3415 | LLString::replaceChar(result, '+', '-'); | 3452 | LLStringUtil::replaceChar(result, '+', '-'); |
3416 | LLString::replaceChar(result, '/', '_'); | 3453 | LLStringUtil::replaceChar(result, '/', '_'); |
3417 | 3454 | ||
3418 | // If you need to transform a GUID to this form on the Mac OS X command line, this will do so: | 3455 | // If you need to transform a GUID to this form on the Mac OS X command line, this will do so: |
3419 | // echo -n x && (echo e669132a-6c43-4ee1-a78d-6c82fff59f32 |xxd -r -p |openssl base64|tr '/+' '_-') | 3456 | // echo -n x && (echo e669132a-6c43-4ee1-a78d-6c82fff59f32 |xxd -r -p |openssl base64|tr '/+' '_-') |
@@ -3435,16 +3472,14 @@ bool LLVoiceClient::IDFromName(const std::string name, LLUUID &uuid) | |||
3435 | 3472 | ||
3436 | // Reverse the transforms done by nameFromID | 3473 | // Reverse the transforms done by nameFromID |
3437 | std::string temp = name; | 3474 | std::string temp = name; |
3438 | LLString::replaceChar(temp, '-', '+'); | 3475 | LLStringUtil::replaceChar(temp, '-', '+'); |
3439 | LLString::replaceChar(temp, '_', '/'); | 3476 | LLStringUtil::replaceChar(temp, '_', '/'); |
3440 | 3477 | ||
3441 | U8 rawuuid[UUID_BYTES + 1]; | 3478 | U8 rawuuid[UUID_BYTES + 1]; |
3442 | int len = apr_base64_decode_binary(rawuuid, temp.c_str() + 1); | 3479 | int len = apr_base64_decode_binary(rawuuid, temp.c_str() + 1); |
3443 | if(len == UUID_BYTES) | 3480 | if(len == UUID_BYTES) |
3444 | { | 3481 | { |
3445 | // The decode succeeded. Stuff the bits into the result's UUID | 3482 | // The decode succeeded. Stuff the bits into the result's UUID |
3446 | // MBW -- XXX -- there's no analogue of LLUUID::toCompressedString that allows you to set a UUID from binary data. | ||
3447 | // The data field is public, so we cheat thusly: | ||
3448 | memcpy(uuid.mData, rawuuid, UUID_BYTES); | 3483 | memcpy(uuid.mData, rawuuid, UUID_BYTES); |
3449 | result = true; | 3484 | result = true; |
3450 | } | 3485 | } |
@@ -3466,7 +3501,7 @@ std::string LLVoiceClient::sipURIFromName(std::string &name) | |||
3466 | result += "@"; | 3501 | result += "@"; |
3467 | result += mAccountServerName; | 3502 | result += mAccountServerName; |
3468 | 3503 | ||
3469 | // LLString::toLower(result); | 3504 | // LLStringUtil::toLower(result); |
3470 | 3505 | ||
3471 | return result; | 3506 | return result; |
3472 | } | 3507 | } |
@@ -3497,6 +3532,45 @@ void LLVoiceClient::enforceTether(void) | |||
3497 | } | 3532 | } |
3498 | } | 3533 | } |
3499 | 3534 | ||
3535 | void LLVoiceClient::updatePosition(void) | ||
3536 | { | ||
3537 | |||
3538 | if(gVoiceClient) | ||
3539 | { | ||
3540 | LLVOAvatar *agent = gAgent.getAvatarObject(); | ||
3541 | LLViewerRegion *region = gAgent.getRegion(); | ||
3542 | if(region && agent) | ||
3543 | { | ||
3544 | LLMatrix3 rot; | ||
3545 | LLVector3d pos; | ||
3546 | |||
3547 | // MBW -- XXX -- Setting both camera and avatar velocity to 0 for now. May figure it out later... | ||
3548 | |||
3549 | // Send the current camera position to the voice code | ||
3550 | rot.setRows(LLViewerCamera::getInstance()->getAtAxis(), LLViewerCamera::getInstance()->getLeftAxis (), LLViewerCamera::getInstance()->getUpAxis()); | ||
3551 | pos = gAgent.getRegion()->getPosGlobalFromRegion(LLViewerCamera::getInstance()->getOrigin()); | ||
3552 | |||
3553 | gVoiceClient->setCameraPosition( | ||
3554 | pos, // position | ||
3555 | LLVector3::zero, // velocity | ||
3556 | rot); // rotation matrix | ||
3557 | |||
3558 | // Send the current avatar position to the voice code | ||
3559 | rot = agent->getRootJoint()->getWorldRotation().getMatrix3(); | ||
3560 | |||
3561 | pos = agent->getPositionGlobal(); | ||
3562 | // MBW -- XXX -- Can we get the head offset from outside the LLVOAvatar? | ||
3563 | // pos += LLVector3d(mHeadOffset); | ||
3564 | pos += LLVector3d(0.f, 0.f, 1.f); | ||
3565 | |||
3566 | gVoiceClient->setAvatarPosition( | ||
3567 | pos, // position | ||
3568 | LLVector3::zero, // velocity | ||
3569 | rot); // rotation matrix | ||
3570 | } | ||
3571 | } | ||
3572 | } | ||
3573 | |||
3500 | void LLVoiceClient::setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot) | 3574 | void LLVoiceClient::setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot) |
3501 | { | 3575 | { |
3502 | mCameraRequestedPosition = position; | 3576 | mCameraRequestedPosition = position; |
@@ -3831,9 +3905,9 @@ F32 LLVoiceClient::getCurrentPower(const LLUUID& id) | |||
3831 | } | 3905 | } |
3832 | 3906 | ||
3833 | 3907 | ||
3834 | LLString LLVoiceClient::getDisplayName(const LLUUID& id) | 3908 | std::string LLVoiceClient::getDisplayName(const LLUUID& id) |
3835 | { | 3909 | { |
3836 | LLString result; | 3910 | std::string result; |
3837 | participantState *participant = findParticipantByID(id); | 3911 | participantState *participant = findParticipantByID(id); |
3838 | if(participant) | 3912 | if(participant) |
3839 | { | 3913 | { |
@@ -4030,17 +4104,17 @@ void LLVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::EStatusTy | |||
4030 | } | 4104 | } |
4031 | 4105 | ||
4032 | //static | 4106 | //static |
4033 | void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data) | 4107 | // void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data) |
4034 | { | 4108 | // { |
4035 | participantState* statep = gVoiceClient->findParticipantByID(id); | 4109 | // participantState* statep = gVoiceClient->findParticipantByID(id); |
4036 | 4110 | ||
4037 | if (statep) | 4111 | // if (statep) |
4038 | { | 4112 | // { |
4039 | statep->mDisplayName = llformat("%s %s", first, last); | 4113 | // statep->mDisplayName = first + " " + last; |
4040 | } | 4114 | // } |
4041 | 4115 | ||
4042 | gVoiceClient->notifyObservers(); | 4116 | // gVoiceClient->notifyObservers(); |
4043 | } | 4117 | // } |
4044 | 4118 | ||
4045 | class LLViewerParcelVoiceInfo : public LLHTTPNode | 4119 | class LLViewerParcelVoiceInfo : public LLHTTPNode |
4046 | { | 4120 | { |
@@ -4052,6 +4126,9 @@ class LLViewerParcelVoiceInfo : public LLHTTPNode | |||
4052 | //the parcel you are in has changed something about its | 4126 | //the parcel you are in has changed something about its |
4053 | //voice information | 4127 | //voice information |
4054 | 4128 | ||
4129 | //this is a misnomer, as it can also be when you are not in | ||
4130 | //a parcel at all. Should really be something like | ||
4131 | //LLViewerVoiceInfoChanged..... | ||
4055 | if ( input.has("body") ) | 4132 | if ( input.has("body") ) |
4056 | { | 4133 | { |
4057 | LLSD body = input["body"]; | 4134 | LLSD body = input["body"]; |
@@ -4061,6 +4138,11 @@ class LLViewerParcelVoiceInfo : public LLHTTPNode | |||
4061 | 4138 | ||
4062 | //body["voice_credentials"] has "channel_uri" (str), | 4139 | //body["voice_credentials"] has "channel_uri" (str), |
4063 | //body["voice_credentials"] has "channel_credentials" (str) | 4140 | //body["voice_credentials"] has "channel_credentials" (str) |
4141 | |||
4142 | //if we really wanted to be extra careful, | ||
4143 | //we'd check the supplied | ||
4144 | //local parcel id to make sure it's for the same parcel | ||
4145 | //we believe we're in | ||
4064 | if ( body.has("voice_credentials") ) | 4146 | if ( body.has("voice_credentials") ) |
4065 | { | 4147 | { |
4066 | LLSD voice_credentials = body["voice_credentials"]; | 4148 | LLSD voice_credentials = body["voice_credentials"]; |