Merge branch 'master' of https://bitbucket.org/Ansariel/phoenix-firestorm-webrtc-voice
# Conflicts: # .github/workflows/build.yaml # indra/newview/CMakeLists.txt # indra/newview/llspeakers.cpp # indra/newview/llvoicechannel.cpp # indra/newview/llvoicechannel.h # indra/newview/llvoiceclient.cpp # indra/newview/llvoiceclient.h # indra/newview/llvoicewebrtc.cppmaster
commit
25b7fd4fa9
|
|
@ -370,15 +370,32 @@ jobs:
|
|||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download viewer exe
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: Windows-app
|
||||
path: _artifacts
|
||||
- name: Download Windows Symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: Windows-symbols
|
||||
- name: Extract viewer pdb
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
shell: bash
|
||||
run: |
|
||||
tar -xJf "${{ needs.build.outputs.viewer_channel }}.sym.tar.xz" -C _artifacts
|
||||
- name: Post Windows symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: secondlife/viewer-build-util/post-bugsplat-windows@v2
|
||||
uses: secondlife-3p/symbol-upload@v10
|
||||
with:
|
||||
username: ${{ env.BUGSPLAT_USER }}
|
||||
password: ${{ env.BUGSPLAT_PASS }}
|
||||
database: "SecondLife_Viewer_2018"
|
||||
channel: ${{ needs.build.outputs.viewer_channel }}
|
||||
application: ${{ needs.build.outputs.viewer_channel }}
|
||||
version: ${{ needs.build.outputs.viewer_version }}
|
||||
directory: _artifacts
|
||||
files: "**/{SecondLifeViewer.exe,llwebrtc.dll,*.pdb}"
|
||||
|
||||
post-mac-symbols:
|
||||
env:
|
||||
|
|
@ -387,15 +404,22 @@ jobs:
|
|||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download Mac Symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: macOS-symbols
|
||||
- name: Post Mac symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: secondlife/viewer-build-util/post-bugsplat-mac@v2
|
||||
uses: secondlife-3p/symbol-upload@v10
|
||||
with:
|
||||
username: ${{ env.BUGSPLAT_USER }}
|
||||
password: ${{ env.BUGSPLAT_PASS }}
|
||||
database: "SecondLife_Viewer_2018"
|
||||
channel: ${{ needs.build.outputs.viewer_channel }}
|
||||
application: ${{ needs.build.outputs.viewer_channel }}
|
||||
version: ${{ needs.build.outputs.viewer_version }} (${{ needs.build.outputs.viewer_version }})
|
||||
directory: .
|
||||
files: "**/*.xcarchive.zip"
|
||||
|
||||
release:
|
||||
needs: [setvar, build, sign-and-package-windows, sign-and-package-mac]
|
||||
|
|
|
|||
7
build.sh
7
build.sh
|
|
@ -170,7 +170,7 @@ pre_build()
|
|||
# This name is consumed by indra/newview/CMakeLists.txt. Make it
|
||||
# absolute because we've had troubles with relative pathnames.
|
||||
abs_build_dir="$(cd "$build_dir"; pwd)"
|
||||
VIEWER_SYMBOL_FILE="$(native_path "$abs_build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.xz")"
|
||||
VIEWER_SYMBOL_FILE="$(native_path "$abs_build_dir/symbols/$variant/${viewer_channel}.sym.tar.xz")"
|
||||
fi
|
||||
|
||||
# honor autobuild_configure_parameters same as sling-buildscripts
|
||||
|
|
@ -523,9 +523,8 @@ then
|
|||
# nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file.
|
||||
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
|
||||
then
|
||||
# BugSplat wants to see xcarchive.zip
|
||||
# e.g. build-darwin-x86_64/newview/Release/Second Life Test.xcarchive.zip
|
||||
symbol_file="${build_dir}/newview/${variant}/${viewer_channel}.xcarchive.zip"
|
||||
# e.g. build-darwin-x86_64/symbols/Release/Second Life Test.xarchive.zip
|
||||
symbol_file="${build_dir}/symbols/${variant}/${viewer_channel}.xcarchive.zip"
|
||||
if [[ ! -f "$symbol_file" ]]
|
||||
then
|
||||
# symbol tarball we prep for (e.g.) Breakpad
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ if (WINDOWS OR DARWIN )
|
|||
endif()
|
||||
else()
|
||||
set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>)
|
||||
set(SYMBOLS_STAGING_DIR ${CMAKE_BINARY_DIR}/symbols/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/${VIEWER_CHANNEL})
|
||||
endif()
|
||||
|
||||
if( DARWIN )
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ namespace LLError
|
|||
};
|
||||
|
||||
/**
|
||||
* @NOTE: addRecorder() and removeRecorder() uses the boost::shared_ptr to allow for shared ownership
|
||||
* @NOTE: addRecorder() and removeRecorder() uses the std::shared_ptr to allow for shared ownership
|
||||
* while still ensuring that the allocated memory is eventually freed
|
||||
*/
|
||||
LL_COMMON_API void addRecorder(RecorderPtr);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include "llsettingsdaycycle.h"
|
||||
#include "llerror.h"
|
||||
#include <algorithm>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include "lltrace.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "v3colorutil.h"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "llsettingswater.h"
|
||||
#include <algorithm>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include "lltrace.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "v3colorutil.h"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ add_library (llwebrtc SHARED ${llwebrtc_SOURCE_FILES})
|
|||
set_target_properties(llwebrtc PROPERTIES PUBLIC_HEADER llwebrtc.h)
|
||||
|
||||
if (WINDOWS)
|
||||
set_target_properties(llwebrtc
|
||||
PROPERTIES
|
||||
LINK_FLAGS "/debug /LARGEADDRESSAWARE"
|
||||
)
|
||||
target_link_libraries(llwebrtc PRIVATE ll::webrtc
|
||||
secur32
|
||||
winmm
|
||||
|
|
@ -38,8 +42,15 @@ if (WINDOWS)
|
|||
msdmo
|
||||
strmiids
|
||||
iphlpapi)
|
||||
if (USE_BUGSPLAT)
|
||||
set_target_properties(llwebrtc PROPERTIES PDB_OUTPUT_DIRECTORY "${SYMBOLS_STAGING_DIR}")
|
||||
endif (USE_BUGSPLAT)
|
||||
elseif (DARWIN)
|
||||
target_link_libraries(llwebrtc PRIVATE ll::webrtc)
|
||||
if (USE_BUGSPLAT)
|
||||
set_target_properties(llwebrtc PROPERTIES XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
|
||||
XCODE_ATTRIBUTE_DWARF_DSYM_FOLDER_PATH "${SYMBOLS_STAGING_DIR}/dSYMs")
|
||||
endif (USE_BUGSPLAT)
|
||||
elseif (LINUX)
|
||||
target_compile_options(llwebrtc PRIVATE "-Wno-deprecated-declarations")
|
||||
target_link_libraries(llwebrtc PRIVATE ll::webrtc)
|
||||
|
|
|
|||
|
|
@ -2659,37 +2659,29 @@ if (INSTALL)
|
|||
include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
|
||||
endif (INSTALL)
|
||||
|
||||
# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
|
||||
if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
|
||||
if (USE_BUGSPLAT)
|
||||
# BugSplat symbol-file generation
|
||||
if (WINDOWS)
|
||||
#<FS:ND> Comment this out, we do our own symbol package which also includes the exe and build_data.json
|
||||
# Just pack up a tarball containing only the .pdb file for the
|
||||
# executable. Because we intend to use cygwin tar, we must render
|
||||
# VIEWER_SYMBOL_FILE in cygwin path syntax.
|
||||
# execute_process(COMMAND "cygpath" "-u" "${VIEWER_SYMBOL_FILE}"
|
||||
# OUTPUT_VARIABLE VIEWER_SYMBOL_FILE_CYGWIN
|
||||
# OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
# execute_process(COMMAND "cygpath" "-u" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
|
||||
# OUTPUT_VARIABLE PARENT_DIRECTORY_CYGWIN
|
||||
# OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
# add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
|
||||
# # Use of 'tar ...J' here assumes VIEWER_SYMBOL_FILE endswith .tar.xz;
|
||||
# # testing a string suffix is painful enough in CMake language that
|
||||
# # we'll continue assuming it until forced to generalize.
|
||||
# set(VIEWER_APP_SYMBOLS_ARCHIVE "${SYMBOLS_STAGING_DIR}.sym.tar.xz")
|
||||
# set_target_properties( ${VIEWER_BINARY_NAME} PROPERTIES PDB_OUTPUT_DIRECTORY "${SYMBOLS_STAGING_DIR}")
|
||||
|
||||
# # Just pack up a tarball containing only the .pdb files for the
|
||||
# # executables.
|
||||
# add_custom_command(OUTPUT "${VIEWER_APP_SYMBOLS_ARCHIVE}"
|
||||
# COMMAND "tar"
|
||||
# ARGS
|
||||
# "cjf"
|
||||
# "${VIEWER_SYMBOL_FILE_CYGWIN}"
|
||||
# "-C"
|
||||
# "${PARENT_DIRECTORY_CYGWIN}"
|
||||
# "firestorm-bin.pdb"
|
||||
# DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/firestorm-bin.pdb"
|
||||
# COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
|
||||
# "cJf"
|
||||
# "${VIEWER_CHANNEL}.sym.tar.xz"
|
||||
# "${VIEWER_CHANNEL}"
|
||||
# DEPENDS "${VIEWER_BINARY_NAME}" llwebrtc
|
||||
# WORKING_DIRECTORY "${SYMBOLS_STAGING_DIR}/.."
|
||||
# COMMENT "Packing viewer PDBs into ${VIEWER_APP_SYMBOLS_ARCHIVE}"
|
||||
# )
|
||||
# add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME})
|
||||
# add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
|
||||
# add_custom_target(generate_symbols DEPENDS "${VIEWER_APP_SYMBOLS_ARCHIVE}")
|
||||
# add_dependencies(generate_symbols ${VIEWER_BINARY_NAME} llwebrtc)
|
||||
|
||||
endif (WINDOWS)
|
||||
if (DARWIN)
|
||||
# Have to run dsymutil first, then pack up the resulting .dSYM directory
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@
|
|||
|
||||
#include "llregioninfomodel.h"
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#include "llatmosphere.h"
|
||||
#include "llagent.h"
|
||||
#include "roles_constants.h"
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@
|
|||
#include "llcorehttputil.h"
|
||||
#include "lleventfilter.h"
|
||||
|
||||
#include "boost/make_shared.hpp"
|
||||
|
||||
#include "llsdutil.h" // <FS:ND/> for ll_pretty_print_sd
|
||||
#include "llviewernetwork.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
#include "llfloatereditenvironmentbase.h"
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// libs
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationsutil.h"
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
#include "llfloaterfixedenvironment.h"
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// libs
|
||||
#include "llbutton.h"
|
||||
#include "llnotifications.h"
|
||||
|
|
|
|||
|
|
@ -131,29 +131,31 @@ void LLOutputMonitorCtrl::draw()
|
|||
//const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL;
|
||||
// </FS:Ansariel> Centralized voice power level
|
||||
|
||||
LLVoiceClient* vocie_client = LLVoiceClient::getInstance();
|
||||
|
||||
if (getVisible() && mAutoUpdate && !getIsMuted() && mSpeakerId.notNull())
|
||||
{
|
||||
setPower(LLVoiceClient::getInstance()->getCurrentPower(mSpeakerId));
|
||||
setPower(vocie_client->getCurrentPower(mSpeakerId));
|
||||
if(mIsAgentControl)
|
||||
{
|
||||
setIsTalking(LLVoiceClient::getInstance()->getUserPTTState());
|
||||
setIsTalking(vocie_client->getUserPTTState());
|
||||
}
|
||||
else
|
||||
{
|
||||
setIsTalking(LLVoiceClient::getInstance()->getIsSpeaking(mSpeakerId));
|
||||
setIsTalking(vocie_client->getIsSpeaking(mSpeakerId));
|
||||
}
|
||||
}
|
||||
|
||||
if ((mPower == 0.f && !mIsTalking) && mShowParticipantsSpeaking)
|
||||
{
|
||||
std::set<LLUUID> participant_uuids;
|
||||
LLVoiceClient::instance().getParticipantList(participant_uuids);
|
||||
vocie_client->getParticipantList(participant_uuids);
|
||||
std::set<LLUUID>::const_iterator part_it = participant_uuids.begin();
|
||||
|
||||
F32 power = 0;
|
||||
for (; part_it != participant_uuids.end(); ++part_it)
|
||||
{
|
||||
power = LLVoiceClient::instance().getCurrentPower(*part_it);
|
||||
power = vocie_client->getCurrentPower(*part_it);
|
||||
if (power)
|
||||
{
|
||||
mPower = power;
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@
|
|||
#include "llvovolume.h"
|
||||
#include "lldrawable.h"
|
||||
#include "llvoavatar.h"
|
||||
//boost
|
||||
#include "boost/make_shared.hpp"
|
||||
|
||||
//...........
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
#include <deque>
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
#include <boost/signals2.hpp>
|
||||
#include <boost/make_shared.hpp> // boost::make_shared
|
||||
|
||||
class LLMessageSystem;
|
||||
class LLViewerTexture;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <boost/make_shared.hpp>
|
||||
#include "lltrace.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "v3colorutil.h"
|
||||
|
|
|
|||
|
|
@ -383,16 +383,17 @@ void LLSpeakerMgr::update(bool resort_ok)
|
|||
}
|
||||
|
||||
// update status of all current speakers
|
||||
bool voice_channel_active = (!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
|
||||
LLVoiceClient* voice_client = LLVoiceClient::getInstance();
|
||||
bool voice_channel_active = (!mVoiceChannel && voice_client->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
|
||||
for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); speaker_it++)
|
||||
{
|
||||
LLUUID speaker_id = speaker_it->first;
|
||||
LLSpeaker* speakerp = speaker_it->second;
|
||||
|
||||
if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id))
|
||||
if (voice_channel_active && voice_client->getVoiceEnabled(speaker_id))
|
||||
{
|
||||
speakerp->mSpeechVolume = LLVoiceClient::getInstance()->getCurrentPower(speaker_id);
|
||||
bool moderator_muted_voice = LLVoiceClient::getInstance()->getIsModeratorMuted(speaker_id);
|
||||
speakerp->mSpeechVolume = voice_client->getCurrentPower(speaker_id);
|
||||
bool moderator_muted_voice = voice_client->getIsModeratorMuted(speaker_id);
|
||||
if (moderator_muted_voice != speakerp->mModeratorMutedVoice)
|
||||
{
|
||||
speakerp->mModeratorMutedVoice = moderator_muted_voice;
|
||||
|
|
@ -400,11 +401,11 @@ void LLSpeakerMgr::update(bool resort_ok)
|
|||
speakerp->fireEvent(new LLSpeakerVoiceModerationEvent(speakerp));
|
||||
}
|
||||
|
||||
if (LLVoiceClient::getInstance()->getOnMuteList(speaker_id) || speakerp->mModeratorMutedVoice)
|
||||
if (voice_client->getOnMuteList(speaker_id) || speakerp->mModeratorMutedVoice)
|
||||
{
|
||||
speakerp->mStatus = LLSpeaker::STATUS_MUTED;
|
||||
}
|
||||
else if (LLVoiceClient::getInstance()->getIsSpeaking(speaker_id))
|
||||
else if (voice_client->getIsSpeaking(speaker_id))
|
||||
{
|
||||
// reset inactivity expiration
|
||||
if (speakerp->mStatus != LLSpeaker::STATUS_SPEAKING)
|
||||
|
|
@ -487,17 +488,18 @@ void LLSpeakerMgr::update(bool resort_ok)
|
|||
void LLSpeakerMgr::updateSpeakerList()
|
||||
{
|
||||
// Are we bound to the currently active voice channel?
|
||||
if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
|
||||
LLVoiceClient* vocie_client = LLVoiceClient::getInstance();
|
||||
if ((!mVoiceChannel && vocie_client->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
|
||||
{
|
||||
std::set<LLUUID> participants;
|
||||
LLVoiceClient::getInstance()->getParticipantList(participants);
|
||||
vocie_client->getParticipantList(participants);
|
||||
// If we are, add all voice client participants to our list of known speakers
|
||||
for (std::set<LLUUID>::iterator participant_it = participants.begin(); participant_it != participants.end(); ++participant_it)
|
||||
{
|
||||
setSpeaker(*participant_it,
|
||||
LLVoiceClient::getInstance()->getDisplayName(*participant_it),
|
||||
vocie_client->getDisplayName(*participant_it),
|
||||
LLSpeaker::STATUS_VOICE_ACTIVE,
|
||||
(LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
|
||||
(vocie_client->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
|
||||
}
|
||||
}
|
||||
else if (mVoiceChannel)
|
||||
|
|
|
|||
|
|
@ -187,13 +187,13 @@ void LLVoiceChannel::handleError(EStatusType type)
|
|||
setState(STATE_ERROR);
|
||||
}
|
||||
|
||||
bool LLVoiceChannel::isActive()
|
||||
bool LLVoiceChannel::isActive() const
|
||||
{
|
||||
// only considered active when currently bound channel matches what our channel
|
||||
return callStarted() && LLVoiceClient::getInstance()->isCurrentChannel(mChannelInfo);
|
||||
}
|
||||
|
||||
bool LLVoiceChannel::callStarted()
|
||||
bool LLVoiceChannel::callStarted() const
|
||||
{
|
||||
return mState >= STATE_CALL_STARTED;
|
||||
}
|
||||
|
|
@ -662,7 +662,7 @@ LLVoiceChannelProximal::LLVoiceChannelProximal() :
|
|||
{
|
||||
}
|
||||
|
||||
bool LLVoiceChannelProximal::isActive()
|
||||
bool LLVoiceChannelProximal::isActive() const
|
||||
{
|
||||
return callStarted() && LLVoiceClient::getInstance()->inProximalChannel();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ public:
|
|||
virtual void activate();
|
||||
virtual void setChannelInfo(const LLSD &channelInfo);
|
||||
virtual void requestChannelInfo();
|
||||
virtual bool isActive();
|
||||
virtual bool callStarted();
|
||||
virtual bool isActive() const;
|
||||
virtual bool callStarted() const;
|
||||
|
||||
// Session name is a UI label used for feedback about which person,
|
||||
// group, or phone number you are talking to
|
||||
|
|
@ -170,7 +170,7 @@ class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton<LLVoice
|
|||
void onChange(EStatusType status, const LLSD &channelInfo, bool proximal) override;
|
||||
void handleStatusChange(EStatusType status) override;
|
||||
void handleError(EStatusType status) override;
|
||||
bool isActive() override;
|
||||
bool isActive() const override;
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -289,15 +289,13 @@ void LLVoiceClient::setNonSpatialVoiceModule(const std::string &voice_server_typ
|
|||
|
||||
void LLVoiceClient::setHidden(bool hidden)
|
||||
{
|
||||
if (mSpatialVoiceModule)
|
||||
{
|
||||
//mSpatialVoiceModule->setHidden(hidden);
|
||||
#ifdef OPENSIM
|
||||
mSpatialVoiceModule->setHidden(hidden && LLGridManager::getInstance()->isInSecondLife());
|
||||
#else
|
||||
mSpatialVoiceModule->setHidden(hidden);
|
||||
#endif
|
||||
}
|
||||
#ifdef OPENSIM
|
||||
LLWebRTCVoiceClient::getInstance()->setHidden(hidden && LLGridManager::getInstance()->isInSecondLife());
|
||||
LLVivoxVoiceClient::getInstance()->setHidden(hidden && LLGridManager::getInstance()->isInSecondLife());
|
||||
#else
|
||||
LLWebRTCVoiceClient::getInstance()->setHidden(hidden);
|
||||
LLVivoxVoiceClient::getInstance()->setHidden(hidden);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLVoiceClient::terminate()
|
||||
|
|
@ -421,13 +419,13 @@ const LLVoiceDeviceList& LLVoiceClient::getRenderDevices()
|
|||
//--------------------------------------------------
|
||||
// participants
|
||||
|
||||
void LLVoiceClient::getParticipantList(std::set<LLUUID> &participants)
|
||||
void LLVoiceClient::getParticipantList(std::set<LLUUID> &participants) const
|
||||
{
|
||||
LLWebRTCVoiceClient::getInstance()->getParticipantList(participants);
|
||||
LLVivoxVoiceClient::getInstance()->getParticipantList(participants);
|
||||
}
|
||||
|
||||
bool LLVoiceClient::isParticipant(const LLUUID &speaker_id)
|
||||
bool LLVoiceClient::isParticipant(const LLUUID &speaker_id) const
|
||||
{
|
||||
return LLWebRTCVoiceClient::getInstance()->isParticipant(speaker_id) ||
|
||||
LLVivoxVoiceClient::getInstance()->isParticipant(speaker_id);
|
||||
|
|
@ -741,12 +739,12 @@ void LLVoiceClient::toggleUserPTTState(void)
|
|||
//-------------------------------------------
|
||||
// nearby speaker accessors
|
||||
|
||||
bool LLVoiceClient::getVoiceEnabled(const LLUUID& id)
|
||||
bool LLVoiceClient::getVoiceEnabled(const LLUUID& id) const
|
||||
{
|
||||
return isParticipant(id);
|
||||
}
|
||||
|
||||
std::string LLVoiceClient::getDisplayName(const LLUUID& id)
|
||||
std::string LLVoiceClient::getDisplayName(const LLUUID& id) const
|
||||
{
|
||||
std::string result = LLWebRTCVoiceClient::getInstance()->getDisplayName(id);
|
||||
if (result.empty())
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class LLVoiceP2PIncomingCallInterface
|
|||
virtual void declineInvite() = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<LLVoiceP2PIncomingCallInterface> LLVoiceP2PIncomingCallInterfacePtr;
|
||||
typedef std::shared_ptr<LLVoiceP2PIncomingCallInterface> LLVoiceP2PIncomingCallInterfacePtr;
|
||||
|
||||
//////////////////////////////////
|
||||
/// @class LLVoiceModuleInterface
|
||||
|
|
@ -479,8 +479,8 @@ public:
|
|||
|
||||
/////////////////////////////
|
||||
// Accessors for data related to nearby speakers
|
||||
bool getVoiceEnabled(const LLUUID& id); // true if we've received data for this avatar
|
||||
std::string getDisplayName(const LLUUID& id);
|
||||
bool getVoiceEnabled(const LLUUID& id) const; // true if we've received data for this avatar
|
||||
std::string getDisplayName(const LLUUID& id) const;
|
||||
bool isOnlineSIP(const LLUUID &id);
|
||||
bool isParticipantAvatar(const LLUUID &id);
|
||||
bool getIsSpeaking(const LLUUID& id);
|
||||
|
|
@ -494,8 +494,8 @@ public:
|
|||
// </FS:Ansariel> Centralized voice power level
|
||||
|
||||
/////////////////////////////
|
||||
void getParticipantList(std::set<LLUUID> &participants);
|
||||
bool isParticipant(const LLUUID& speaker_id);
|
||||
void getParticipantList(std::set<LLUUID> &participants) const;
|
||||
bool isParticipant(const LLUUID& speaker_id) const;
|
||||
|
||||
//////////////////////////
|
||||
/// @name text chat
|
||||
|
|
|
|||
|
|
@ -2252,7 +2252,6 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
|
|||
|
||||
mIsInChannel = true;
|
||||
mMuteMicDirty = true;
|
||||
mSessionTerminateRequested = false;
|
||||
|
||||
while (!sShuttingDown
|
||||
&& mVoiceEnabled
|
||||
|
|
@ -5117,7 +5116,7 @@ void LLVivoxVoiceClient::hangup() { leaveChannel(); }
|
|||
|
||||
LLVoiceP2PIncomingCallInterfacePtr LLVivoxVoiceClient::getIncomingCallInterface(const LLSD &voice_call_info)
|
||||
{
|
||||
return boost::make_shared<LLVivoxVoiceP2PIncomingCall>(voice_call_info);
|
||||
return std::make_shared<LLVivoxVoiceP2PIncomingCall>(voice_call_info);
|
||||
}
|
||||
|
||||
bool LLVivoxVoiceClient::answerInvite(const std::string &sessionHandle)
|
||||
|
|
@ -5241,7 +5240,9 @@ void LLVivoxVoiceClient::processChannels(bool process)
|
|||
|
||||
bool LLVivoxVoiceClient::isCurrentChannel(const LLSD &channelInfo)
|
||||
{
|
||||
if (!mProcessChannels || (channelInfo.has("voice_server_type") && channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE))
|
||||
if (!mProcessChannels
|
||||
|| (channelInfo.has("voice_server_type") && channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE)
|
||||
|| mSessionTerminateRequested)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -5578,8 +5579,8 @@ void LLVivoxVoiceClient::leaveChannel(void)
|
|||
{
|
||||
LL_DEBUGS("Voice") << "leaving channel for teleport/logout" << LL_ENDL;
|
||||
mChannelName.clear();
|
||||
sessionTerminate();
|
||||
}
|
||||
sessionTerminate();
|
||||
}
|
||||
|
||||
void LLVivoxVoiceClient::setMuteMic(bool muted)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ public:
|
|||
// Returns true if vivox has successfully logged in and is not in error state
|
||||
bool isVoiceWorking() const override;
|
||||
|
||||
void setHidden(bool hidden) override; // virtual
|
||||
|
||||
/////////////////////
|
||||
/// @name Tuning
|
||||
//@{
|
||||
|
|
@ -760,7 +762,6 @@ private:
|
|||
LLSD getAudioSessionChannelInfo();
|
||||
std::string getAudioSessionHandle();
|
||||
|
||||
void setHidden(bool hidden) override; //virtual
|
||||
void sendPositionAndVolumeUpdate(void);
|
||||
|
||||
void sendCaptureAndRenderDevices();
|
||||
|
|
|
|||
|
|
@ -457,6 +457,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
|
|||
// Could help with voice updates making for smoother
|
||||
// voice when we're busy.
|
||||
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
|
||||
if (sShuttingDown) return; // 'this' migh already be invalid
|
||||
bool voiceEnabled = mVoiceEnabled;
|
||||
|
||||
if (!isAgentAvatarValid())
|
||||
|
|
@ -1253,7 +1254,7 @@ void LLWebRTCVoiceClient::sessionState::removeParticipant(const LLWebRTCVoiceCli
|
|||
LLWebRTCVoiceClient::getInstance()->notifyParticipantObservers();
|
||||
}
|
||||
}
|
||||
if (mHangupOnLastLeave && (participantID != gAgentID) && (mParticipantsByUUID.size() <= 1))
|
||||
if (mHangupOnLastLeave && (participantID != gAgentID) && (mParticipantsByUUID.size() <= 1) && LLWebRTCVoiceClient::instanceExists())
|
||||
{
|
||||
LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
|
||||
}
|
||||
|
|
@ -1964,8 +1965,8 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates()
|
|||
|
||||
for (auto &connection : mWebRTCConnections)
|
||||
{
|
||||
boost::shared_ptr<LLVoiceWebRTCSpatialConnection> spatialConnection =
|
||||
boost::static_pointer_cast<LLVoiceWebRTCSpatialConnection>(connection);
|
||||
std::shared_ptr<LLVoiceWebRTCSpatialConnection> spatialConnection =
|
||||
std::static_pointer_cast<LLVoiceWebRTCSpatialConnection>(connection);
|
||||
|
||||
LLUUID regionID = spatialConnection.get()->getRegionID();
|
||||
|
||||
|
|
@ -2187,47 +2188,47 @@ void LLVoiceWebRTCConnection::processIceUpdates()
|
|||
{
|
||||
mOutstandingRequests++;
|
||||
LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::processIceUpdatesCoro",
|
||||
boost::bind(&LLVoiceWebRTCConnection::processIceUpdatesCoro, this));
|
||||
boost::bind(&LLVoiceWebRTCConnection::processIceUpdatesCoro, this->shared_from_this()));
|
||||
}
|
||||
|
||||
// Ice candidates may be streamed in before or after the SDP offer is available (see below)
|
||||
// This function determines whether candidates are available to send to the Secondlife WebRTC
|
||||
// server via the simulator. If so, and there are no more candidates, this code
|
||||
// will make the cap call to the server sending up the ICE candidates.
|
||||
void LLVoiceWebRTCConnection::processIceUpdatesCoro()
|
||||
void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
|
||||
|
||||
if (mShutDown || LLWebRTCVoiceClient::isShuttingDown())
|
||||
if (connection->mShutDown || LLWebRTCVoiceClient::isShuttingDown())
|
||||
{
|
||||
mOutstandingRequests--;
|
||||
connection->mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
bool iceCompleted = false;
|
||||
LLSD body;
|
||||
if (!mIceCandidates.empty() || mIceCompleted)
|
||||
if (!connection->mIceCandidates.empty() || connection->mIceCompleted)
|
||||
{
|
||||
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
|
||||
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(connection->mRegionID);
|
||||
if (!regionp || !regionp->capabilitiesReceived())
|
||||
{
|
||||
LL_DEBUGS("Voice") << "no capabilities for ice gathering; waiting " << LL_ENDL;
|
||||
mOutstandingRequests--;
|
||||
connection->mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = regionp->getCapability("VoiceSignalingRequest");
|
||||
if (url.empty())
|
||||
{
|
||||
mOutstandingRequests--;
|
||||
connection->mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
LL_DEBUGS("Voice") << "region ready to complete voice signaling; url=" << url << LL_ENDL;
|
||||
if (!mIceCandidates.empty())
|
||||
if (!connection->mIceCandidates.empty())
|
||||
{
|
||||
LLSD candidates = LLSD::emptyArray();
|
||||
for (auto &ice_candidate : mIceCandidates)
|
||||
for (auto &ice_candidate : connection->mIceCandidates)
|
||||
{
|
||||
LLSD body_candidate;
|
||||
body_candidate["sdpMid"] = ice_candidate.mSdpMid;
|
||||
|
|
@ -2236,18 +2237,18 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro()
|
|||
candidates.append(body_candidate);
|
||||
}
|
||||
body["candidates"] = candidates;
|
||||
mIceCandidates.clear();
|
||||
connection->mIceCandidates.clear();
|
||||
}
|
||||
else if (mIceCompleted)
|
||||
else if (connection->mIceCompleted)
|
||||
{
|
||||
LLSD body_candidate;
|
||||
body_candidate["completed"] = true;
|
||||
body["candidate"] = body_candidate;
|
||||
iceCompleted = mIceCompleted;
|
||||
mIceCompleted = false;
|
||||
iceCompleted = connection->mIceCompleted;
|
||||
connection->mIceCompleted = false;
|
||||
}
|
||||
|
||||
body["viewer_session"] = mViewerSession;
|
||||
body["viewer_session"] = connection->mViewerSession;
|
||||
body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
|
||||
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
|
||||
|
|
@ -2262,7 +2263,7 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro()
|
|||
|
||||
if (LLWebRTCVoiceClient::isShuttingDown())
|
||||
{
|
||||
mOutstandingRequests--;
|
||||
connection->mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2272,10 +2273,10 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro()
|
|||
if (!status)
|
||||
{
|
||||
// couldn't trickle the candidates, so restart the session.
|
||||
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
|
||||
connection->setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
|
||||
}
|
||||
}
|
||||
mOutstandingRequests--;
|
||||
connection->mOutstandingRequests--;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2423,31 +2424,31 @@ void LLVoiceWebRTCConnection::sendData(const std::string &data)
|
|||
|
||||
// Tell the simulator that we're shutting down a voice connection.
|
||||
// The simulator will pass this on to the Secondlife WebRTC server.
|
||||
void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
|
||||
void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connection)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
|
||||
|
||||
LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL;
|
||||
if (mWebRTCDataInterface)
|
||||
if (connection->mWebRTCDataInterface)
|
||||
{
|
||||
mWebRTCDataInterface->unsetDataObserver(this);
|
||||
mWebRTCDataInterface = nullptr;
|
||||
connection->mWebRTCDataInterface->unsetDataObserver(connection.get());
|
||||
connection->mWebRTCDataInterface = nullptr;
|
||||
}
|
||||
mWebRTCAudioInterface = nullptr;
|
||||
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
|
||||
connection->mWebRTCAudioInterface = nullptr;
|
||||
LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(connection->mRegionID);
|
||||
if (!regionp || !regionp->capabilitiesReceived())
|
||||
{
|
||||
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
|
||||
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
|
||||
mOutstandingRequests--;
|
||||
connection->setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
|
||||
connection->mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string url = regionp->getCapability("ProvisionVoiceAccountRequest");
|
||||
if (url.empty())
|
||||
{
|
||||
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
|
||||
mOutstandingRequests--;
|
||||
connection->setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
|
||||
connection->mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2456,7 +2457,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
|
|||
LLVoiceWebRTCStats::getInstance()->provisionAttemptStart();
|
||||
LLSD body;
|
||||
body["logout"] = true;
|
||||
body["viewer_session"] = mViewerSession;
|
||||
body["viewer_session"] = connection->mViewerSession;
|
||||
body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
|
||||
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
|
||||
|
|
@ -2467,16 +2468,16 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
|
|||
|
||||
httpOpts->setWantHeaders(true);
|
||||
|
||||
mOutstandingRequests++;
|
||||
connection->mOutstandingRequests++;
|
||||
|
||||
// tell the server to shut down the connection as a courtesy.
|
||||
// shutdownConnection will drop the WebRTC connection which will
|
||||
// also shut things down.
|
||||
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
|
||||
|
||||
mOutstandingRequests--;
|
||||
setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
|
||||
}
|
||||
connection->mOutstandingRequests--;
|
||||
connection->setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
|
||||
}
|
||||
|
||||
// Tell the simulator to tell the Secondlife WebRTC server that we want a voice
|
||||
// connection. The SDP is sent up as part of this, and the simulator will respond
|
||||
|
|
@ -2659,7 +2660,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
|
|||
// VOICE_STATE_SESSION_ESTABLISHED via a callback on a webrtc thread.
|
||||
setVoiceConnectionState(VOICE_STATE_CONNECTION_WAIT);
|
||||
LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::requestVoiceConnectionCoro",
|
||||
boost::bind(&LLVoiceWebRTCConnection::requestVoiceConnectionCoro, this));
|
||||
boost::bind(&LLVoiceWebRTCConnection::requestVoiceConnectionCoro, this->shared_from_this()));
|
||||
break;
|
||||
|
||||
case VOICE_STATE_CONNECTION_WAIT:
|
||||
|
|
@ -2739,7 +2740,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
|
|||
case VOICE_STATE_DISCONNECT:
|
||||
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT);
|
||||
LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro",
|
||||
boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this));
|
||||
boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this->shared_from_this()));
|
||||
break;
|
||||
|
||||
case VOICE_STATE_WAIT_FOR_EXIT:
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class LLWebRTCProtocolParser;
|
|||
|
||||
class LLAvatarName;
|
||||
class LLVoiceWebRTCConnection;
|
||||
typedef boost::shared_ptr<LLVoiceWebRTCConnection> connectionPtr_t;
|
||||
typedef std::shared_ptr<LLVoiceWebRTCConnection> connectionPtr_t;
|
||||
|
||||
extern const std::string WEBRTC_VOICE_SERVER_TYPE;
|
||||
|
||||
|
|
@ -88,6 +88,7 @@ public:
|
|||
std::string sipURIFromID(const LLUUID &id) const override;
|
||||
LLSD getP2PChannelInfoTemplate(const LLUUID& id) const override;
|
||||
|
||||
void setHidden(bool hidden) override; // virtual
|
||||
|
||||
///////////////////
|
||||
/// @name Logging
|
||||
|
|
@ -252,7 +253,7 @@ public:
|
|||
bool mIsModeratorMuted;
|
||||
LLUUID mRegion;
|
||||
};
|
||||
typedef boost::shared_ptr<participantState> participantStatePtr_t;
|
||||
typedef std::shared_ptr<participantState> participantStatePtr_t;
|
||||
|
||||
participantStatePtr_t findParticipantByID(const std::string &channelID, const LLUUID &id);
|
||||
participantStatePtr_t addParticipantByID(const std::string& channelID, const LLUUID &id, const LLUUID& region);
|
||||
|
|
@ -265,10 +266,10 @@ public:
|
|||
class sessionState
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<sessionState> ptr_t;
|
||||
typedef boost::weak_ptr<sessionState> wptr_t;
|
||||
typedef std::shared_ptr<sessionState> ptr_t;
|
||||
typedef std::weak_ptr<sessionState> wptr_t;
|
||||
|
||||
typedef boost::function<void(const ptr_t &)> sessionFunc_t;
|
||||
typedef std::function<void(const ptr_t &)> sessionFunc_t;
|
||||
|
||||
static void addSession(const std::string &channelID, ptr_t& session);
|
||||
virtual ~sessionState();
|
||||
|
|
@ -336,7 +337,7 @@ public:
|
|||
sessionFunc_t func);
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<sessionState> sessionStatePtr_t;
|
||||
typedef std::shared_ptr<sessionState> sessionStatePtr_t;
|
||||
typedef std::map<std::string, sessionStatePtr_t> sessionMap;
|
||||
|
||||
class estateSessionState : public sessionState
|
||||
|
|
@ -480,8 +481,6 @@ private:
|
|||
|
||||
LLSD getAudioSessionChannelInfo();
|
||||
|
||||
void setHidden(bool hidden) override; //virtual
|
||||
|
||||
void enforceTether();
|
||||
|
||||
void updateNeighboringRegions();
|
||||
|
|
@ -576,7 +575,8 @@ class LLVoiceWebRTCStats : public LLSingleton<LLVoiceWebRTCStats>
|
|||
|
||||
class LLVoiceWebRTCConnection :
|
||||
public llwebrtc::LLWebRTCSignalingObserver,
|
||||
public llwebrtc::LLWebRTCDataObserver
|
||||
public llwebrtc::LLWebRTCDataObserver,
|
||||
public std::enable_shared_from_this<LLVoiceWebRTCConnection>
|
||||
{
|
||||
public:
|
||||
LLVoiceWebRTCConnection(const LLUUID ®ionID, const std::string &channelID);
|
||||
|
|
@ -610,7 +610,7 @@ class LLVoiceWebRTCConnection :
|
|||
|
||||
void processIceUpdates();
|
||||
|
||||
void processIceUpdatesCoro();
|
||||
static void processIceUpdatesCoro(connectionPtr_t connection);
|
||||
|
||||
virtual void setMuteMic(bool muted);
|
||||
virtual void setSpeakerVolume(F32 volume);
|
||||
|
|
@ -677,9 +677,9 @@ class LLVoiceWebRTCConnection :
|
|||
}
|
||||
|
||||
virtual void requestVoiceConnection() = 0;
|
||||
void requestVoiceConnectionCoro() { requestVoiceConnection(); }
|
||||
static void requestVoiceConnectionCoro(connectionPtr_t connection) { connection->requestVoiceConnection(); }
|
||||
|
||||
void breakVoiceConnectionCoro();
|
||||
static void breakVoiceConnectionCoro(connectionPtr_t connection);
|
||||
|
||||
LLVoiceClientStatusObserver::EStatusType mCurrentStatus;
|
||||
|
||||
|
|
|
|||
|
|
@ -3627,7 +3627,7 @@ Wenn Sie Premium-Mitglied sind, [[PREMIUM_URL] klicken Sie hier], um Ihren Voice
|
|||
<notification name="VoiceEffectsNotSupported">
|
||||
Voice-Morph-Effekte werden von diesem Viewer nicht unterstützt.
|
||||
Für weitere Informationen zu anderen Voice-Morphing-Tools, lesen Sie bitte [[FAQ_URL] diesen Artikel].
|
||||
<usetemplate name="okignore" yestext="OK"/>
|
||||
<usetemplate ignoretext="Warnen, falls Voice-Morphing nicht unterstützt wird" name="okignore" yestext="OK"/>
|
||||
</notification>
|
||||
<notification name="Cannot enter parcel: not a group member">
|
||||
Nur Mitglieder einer bestimmten Gruppe dürfen diesen Bereich betreten.
|
||||
|
|
|
|||
|
|
@ -9507,6 +9507,7 @@ New Voice Morphs are available!
|
|||
Voice Morphs are not supported by this viewer.
|
||||
For more information about other voice morph tools, see [[FAQ_URL] this article].
|
||||
<usetemplate
|
||||
ignoretext="Warn me about voice morph not being supported"
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
<tag>voice</tag>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@
|
|||
<menu_item_call label="Вернуть" name="Return..."/>
|
||||
<menu_item_call label="Взять" name="Pie Object Take"/>
|
||||
<menu_item_call label="Взять копию" name="Take Copy"/>
|
||||
<menu_item_call label="Взять как комбинированный предмет" name="Take combined"/>
|
||||
<menu_item_call label="Взять копию как комбинированный предмет" name="Take Copy combined"/>
|
||||
<menu_item_call label="Взять как отдельные предметы" name="Take Separate"/>
|
||||
<menu_item_call label="Взять копии как отдельные предметы" name="Take Copy Separate"/>
|
||||
<menu_item_call label="Заплатить" name="Pay..."/>
|
||||
<menu_item_call label="Купить" name="Buy..."/>
|
||||
<context_menu label="Сохранить как" name="Export Menu">
|
||||
|
|
|
|||
|
|
@ -16,15 +16,12 @@
|
|||
|
||||
<layout_stack name="group_info_sidetray_main">
|
||||
<layout_panel name="header_container">
|
||||
|
||||
<panel name="group_info_top">
|
||||
<text_editor name="group_name" value="(Загрузка...)"/>
|
||||
<line_editor label="Введите здесь название новой группы" name="group_name_editor"/>
|
||||
</panel>
|
||||
|
||||
</layout_panel>
|
||||
<layout_panel name="group_info_content">
|
||||
|
||||
<layout_stack name="layout">
|
||||
<layout_panel name="group_accordions">
|
||||
<accordion name="groups_accordion">
|
||||
|
|
@ -37,6 +34,9 @@
|
|||
</layout_panel>
|
||||
</layout_stack>
|
||||
<layout_stack name="button_row_ls">
|
||||
<layout_panel name="btn_activate_lp">
|
||||
<button label="Активация" name="btn_activate"/>
|
||||
</layout_panel>
|
||||
<layout_panel name="btn_chat_lp">
|
||||
<button label="Чат" name="btn_chat"/>
|
||||
</layout_panel>
|
||||
|
|
@ -48,7 +48,6 @@
|
|||
<button label="Создать группу" name="btn_create" tool_tip="Создать новую группу"/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
</panel>
|
||||
|
|
|
|||
|
|
@ -88,12 +88,19 @@
|
|||
<slider label="Расстояние прорисовки" name="DrawDistance"/>
|
||||
<text name="DrawDistanceMeterText2">m</text>
|
||||
<slider label="Максимум частиц" name="MaxParticleCount"/>
|
||||
<text name="AvatarComplexityModeLabel">Отображение аватара</text>
|
||||
<combo_box name="AvatarComplexityMode">
|
||||
<combo_box.item label="Огранич. по сложности" name="0"/>
|
||||
<combo_box.item label="Всегда показ. друзей" name="1"/>
|
||||
<combo_box.item label="Показ. только друзей" name="2"/>
|
||||
</combo_box>
|
||||
<slider label="Максимальная сложность" name="IndirectMaxComplexity" tool_tip="Контролирует, в какой момент визуально сложный аватар отобразится как силуэт"/>
|
||||
<slider label="Максимум 3D аватаров" name="IndirectMaxNonImpostors"/>
|
||||
<slider label="Послеоперационне качество" name="RenderPostProcess"/>
|
||||
<text name="PostProcessText">
|
||||
Низкое
|
||||
</text>
|
||||
<slider label="Макс. кол-во источников света" name="MaxLights"/>
|
||||
<slider label="Физика аватаров" name="AvatarPhysicsDetail"/>
|
||||
<slider label="Экспозиция:" name="RenderExposure"/>
|
||||
<text name="MeshDetailText">
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@
|
|||
<radio_item label="Слышать все голоса громко (только Open Sim)" name="2"/>
|
||||
</radio_group>
|
||||
<check_box label="Двигать губами аватара во время разговора" name="enable_lip_sync"/>
|
||||
<check_box label="Подавление эха" name="enable_echo_cancellation" tool_tip="Установите флажок, чтобы включить подавление голосового эха"/>
|
||||
<check_box label="Показать голосовой индикатор над аватарами" tool_tip="Показывает голосовой индикатор (белую точку) над аватарами" name="FSShowVoiceVisualizer"/>
|
||||
<check_box label="Показать голосовой индикатор над моим аватаром" name="FSShowMyOwnVoiceVisualizer"/>
|
||||
<check_box label="Показывать точку как часть голосового индикатора" tool_tip="Если этот параметр включен, точка отображается как часть голосового индикатора. Если отключено, отображаются только голосовые волны." name="FSShowVoiceVisualizerWithDot"/>
|
||||
|
|
@ -120,6 +121,15 @@
|
|||
<check_box label="Автоматически отклонять все входящие специальные голосовые вызовы AdHoc" name="VoiceCallsRejectAdHoc"/>
|
||||
<check_box label="Автоматически отклонять все входящие P2P (аватар с аватаром) голосовые вызовы" name="VoiceCallsRejectP2P"/>
|
||||
<check_box label="Включить/выключить микрофон при нажатии кнопки на панели инструментов" name="push_to_talk_toggle_check" tool_tip="В режиме 'Включить/выключить' микрофон включается и выключается одиночным нажатием кнопки. Иначе микрофон включен только когда нажата кнопка."/>
|
||||
<check_box label="Автоматическая регулировка усиления" name="voice_automatic_gain_control" tool_tip="Установите флажок, чтобы включить автоматическую регулировку усиления"/>
|
||||
<text name="noise_suppression_label" width="105" >Шумоподавление</text>
|
||||
<combo_box name="noise_suppression_combo">
|
||||
<item label="Выключено" name="noise_suppression_none"/>
|
||||
<item label="Низкое" name="noise_suppression_low"/>
|
||||
<item label="Умеренное" name="noise_suppression_moderate"/>
|
||||
<item label="Высокое" name="noise_suppression_high"/>
|
||||
<item label="Максимум" name="noise_suppression_max"/>
|
||||
</combo_box>
|
||||
<button label="Настройки звукового устройства" name="device_settings_btn"/>
|
||||
<panel label="Настройки устройства" name="device_settings_panel">
|
||||
<panel.string name="default_text">
|
||||
|
|
|
|||
Loading…
Reference in New Issue