From 6459a3c5aaa94053ffe667da9268efc4f2bd3e46 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 6 Aug 2025 22:23:22 +0300 Subject: #4297 Crash on LLVOCache::writeToCache handle/iter existed, but entry was null --- indra/newview/llvocache.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 27c105c8d6..501828eee8 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -1875,11 +1875,11 @@ void LLVOCache::removeGenericExtrasForHandle(U64 handle) } // NOTE: when removing the extras, we must also remove the objects so the simulator will send us a full upddate with the valid overrides - auto* entry = mHandleEntryMap[handle]; - if (entry) + handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle); + if (iter != mHandleEntryMap.end()) { - LL_WARNS("GLTF", "VOCache") << "Removing generic extras for handle " << entry->mHandle << "Filename: " << getObjectCacheExtrasFilename(handle) << LL_ENDL; - removeEntry(entry); + LL_WARNS("GLTF", "VOCache") << "Removing generic extras for handle " << handle << "Filename: " << getObjectCacheExtrasFilename(handle) << LL_ENDL; + removeEntry(iter->second); } else { -- cgit v1.2.3 From 93a66b47645755d8811d3420f772c1a606b53d40 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 6 Aug 2025 22:34:28 +0300 Subject: #4470 Hide discord panel when set to build without discord --- indra/newview/llfloaterpreference.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index fff005872c..9fb9c6346e 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -529,7 +529,8 @@ bool LLFloaterPreference::postBuild() } #ifndef LL_DISCORD - getChild("privacy_tab_container")->childDisable("privacy_preferences_discord"); + LLPanel* panel = getChild("privacy_preferences_discord"); + getChild("privacy_tab_container")->removeTabPanel(panel); #endif return true; -- cgit v1.2.3 From 8ef660a7450dad60e5f73cd2cc50aeb6b9f8a356 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 8 Aug 2025 21:57:28 +0300 Subject: #4503 Crash at openHeaderEntriesFile --- indra/newview/lltexturecache.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 442c627d07..1a7ce74ccc 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1354,6 +1354,7 @@ U32 LLTextureCache::openAndReadEntries(std::vector& entries) if (bytes_read < sizeof(Entry)) { LL_WARNS() << "Corrupted header entries, failed at " << idx << " / " << num_entries << LL_ENDL; + closeHeaderEntriesFile(); return 0; } entries.push_back(entry); -- cgit v1.2.3 From bab2c12d048e7faf021ee3a9df39251e91973abf Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Wed, 6 Aug 2025 11:48:44 -0700 Subject: Straighten out muting to prevent echo when crossing from vivox to webrtc regions. Muting was a bit random in the code, so it's now been straightened out and should prevent echo. Also, code was added to not attempt connection to non-webrtc regions in the webrtc code. --- indra/llwebrtc/llwebrtc.cpp | 6 ++-- indra/newview/llvoicewebrtc.cpp | 65 +++++++++++++++++++++++++++++++++++------ indra/newview/llvoicewebrtc.h | 3 ++ 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 28639b9af0..20951ff816 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -904,12 +904,12 @@ void LLWebRTCPeerConnectionImpl::enableSenderTracks(bool enable) // set_enabled shouldn't be done on the worker thread. if (mPeerConnection) { + mPeerConnection->SetAudioRecording(enable); auto senders = mPeerConnection->GetSenders(); for (auto &sender : senders) { sender->track()->set_enabled(enable); } - mPeerConnection->SetAudioRecording(enable); } } @@ -964,6 +964,9 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute) { if (mPeerConnection) { + // SetAudioRecording must be called before enabling/disabling tracks. + mPeerConnection->SetAudioRecording(enable); + auto senders = mPeerConnection->GetSenders(); RTC_LOG(LS_INFO) << __FUNCTION__ << (mMute ? "disabling" : "enabling") << " streams count " << senders.size(); @@ -982,7 +985,6 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute) track->set_enabled(enable); } } - mPeerConnection->SetAudioRecording(enable); } }); } diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 627d759df4..194e855aa6 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -52,6 +52,7 @@ #include "llcachename.h" #include "llimview.h" // for LLIMMgr #include "llworld.h" +#include "llviewerregion.h" #include "llparcel.h" #include "llviewerparcelmgr.h" #include "llfirstuse.h" @@ -2004,6 +2005,33 @@ bool LLWebRTCVoiceClient::sessionState::processConnectionStates() return !mWebRTCConnections.empty(); } +// Helper function to check if a region supports WebRTC voice +bool LLWebRTCVoiceClient::estateSessionState::isRegionWebRTCEnabled(const LLUUID& regionID) +{ + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromID(regionID); + if (!region) + { + LL_WARNS("Voice") << "Could not find region " << regionID + << " for voice server type validation" << LL_ENDL; + return false; + } + + LLSD simulatorFeatures; + region->getSimulatorFeatures(simulatorFeatures); + + bool isWebRTCEnabled = simulatorFeatures.has("VoiceServerType") && + simulatorFeatures["VoiceServerType"].asString() == "webrtc"; + + if (!isWebRTCEnabled) + { + LL_DEBUGS("Voice") << "Region " << regionID << " VoiceServerType is not 'webrtc' (got: " + << (simulatorFeatures.has("VoiceServerType") ? simulatorFeatures["VoiceServerType"].asString() : "none") << ")" + << LL_ENDL; + } + + return isWebRTCEnabled; +} + // processing of spatial voice connection states requires special handling. // as neighboring regions need to be started up or shut down depending // on our location. @@ -2028,6 +2056,13 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates() // shut down connections to neighbors that are too far away. spatialConnection.get()->shutDown(); } + else if (!isRegionWebRTCEnabled(regionID)) + { + // shut down connections to neighbors that no longer support WebRTC voice. + LL_DEBUGS("Voice") << "Shutting down connection to neighbor region " << regionID + << " - no longer supports WebRTC voice" << LL_ENDL; + spatialConnection.get()->shutDown(); + } if (!spatialConnection.get()->isShuttingDown()) { neighbor_ids.erase(regionID); @@ -2037,11 +2072,20 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates() // add new connections for new neighbors for (auto &neighbor : neighbor_ids) { - connectionPtr_t connection(new LLVoiceWebRTCSpatialConnection(neighbor, INVALID_PARCEL_ID, mChannelID)); + // Only connect if the region supports WebRTC voice server type + if (isRegionWebRTCEnabled(neighbor)) + { + connectionPtr_t connection(new LLVoiceWebRTCSpatialConnection(neighbor, INVALID_PARCEL_ID, mChannelID)); - mWebRTCConnections.push_back(connection); - connection->setMuteMic(mMuted); - connection->setSpeakerVolume(mSpeakerVolume); + mWebRTCConnections.push_back(connection); + connection->setMuteMic(mMuted); // mute will be set for primary connection when that connection comes up + connection->setSpeakerVolume(mSpeakerVolume); + } + else + { + LL_DEBUGS("Voice") << "Skipping neighbor region " << neighbor + << " - does not support WebRTC voice" << LL_ENDL; + } } } return LLWebRTCVoiceClient::sessionState::processConnectionStates(); @@ -2391,6 +2435,7 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac } LL_DEBUGS("Voice") << "On AudioEstablished." << LL_ENDL; mWebRTCAudioInterface = audio_interface; + mWebRTCAudioInterface->setMute(true); // mute will be set appropriately later when we finish setting up. setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED); }); } @@ -2750,7 +2795,8 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() } // update the peer connection with the various characteristics of // this connection. - mWebRTCAudioInterface->setMute(mMuted); + // this connection will come up as muted, but will be set to the appropriate + // value later on. mWebRTCAudioInterface->setReceiveVolume(mSpeakerVolume); LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID, mRegionID); setVoiceConnectionState(VOICE_STATE_WAIT_FOR_DATA_CHANNEL); @@ -2795,6 +2841,10 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() if (primary != mPrimary) { mPrimary = primary; + if (mWebRTCAudioInterface) + { + mWebRTCAudioInterface->setMute(mMuted || !mPrimary); + } sendJoin(); } } @@ -3097,10 +3147,7 @@ LLVoiceWebRTCSpatialConnection::LLVoiceWebRTCSpatialConnection(const LLUUID ® LLVoiceWebRTCConnection(regionID, channelID), mParcelLocalID(parcelLocalID) { - if (gAgent.getRegion()) - { - mPrimary = (regionID == gAgent.getRegion()->getRegionID()); - } + mPrimary = false; // will be set to primary after connection established } LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection() diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index ff82d2739d..71347f206a 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -351,6 +351,9 @@ public: bool isSpatial() override { return true; } bool isEstate() override { return true; } bool isCallbackPossible() override { return false; } + + private: + bool isRegionWebRTCEnabled(const LLUUID& regionID); }; class parcelSessionState : public sessionState -- cgit v1.2.3