diff options
Diffstat (limited to 'indra')
76 files changed, 1368 insertions, 904 deletions
| diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index cc217b0563..0a00ccbb5b 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -20,6 +20,7 @@ set(cmake_SOURCE_FILES          Copy3rdPartyLibs.cmake          DBusGlib.cmake          DeploySharedLibs.cmake +        Discord.cmake          DragDrop.cmake          EXPAT.cmake          FindAutobuild.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 6ac00fd131..0153e69d5b 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -6,6 +6,9 @@  include(CMakeCopyIfDifferent)  include(Linking) +if (USE_DISCORD) +  include(Discord) +endif ()  include(OPENAL)  # When we copy our dependent libraries, we almost always want to copy them to @@ -75,6 +78,10 @@ if(WINDOWS)        endif(ADDRESS_SIZE EQUAL 32)      endif (USE_BUGSPLAT) +    if (TARGET ll::discord_sdk) +        list(APPEND release_files discord_partner_sdk.dll) +    endif () +      if (TARGET ll::openal)          list(APPEND release_files openal32.dll alut.dll)      endif () @@ -180,6 +187,10 @@ elseif(DARWIN)              )      endif() +    if (TARGET ll::discord_sdk) +      list(APPEND release_files libdiscord_partner_sdk.dylib) +    endif () +      if (TARGET ll::openal)        list(APPEND release_files libalut.dylib libopenal.dylib)      endif () diff --git a/indra/cmake/Discord.cmake b/indra/cmake/Discord.cmake new file mode 100644 index 0000000000..95cfaacf5b --- /dev/null +++ b/indra/cmake/Discord.cmake @@ -0,0 +1,11 @@ +include(Prebuilt) + +include_guard() + +add_library(ll::discord_sdk INTERFACE IMPORTED) +target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1) + +use_prebuilt_binary(discord_sdk) + +target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk) +target_link_libraries(ll::discord_sdk INTERFACE discord_partner_sdk) diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 778b253c3c..7007049e1c 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2228,6 +2228,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)      registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));      registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));      registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url)); +    registrar.add("Url.ShowParcelOnMap", boost::bind(&LLUrlAction::showParcelOnMap, url));      registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));      registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url)); diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index b6b450c2a1..ce599a7552 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -30,6 +30,7 @@  #include "llview.h"  #include "llwindow.h"  #include "llurlregistry.h" +#include "v3dmath.h"  // global state for the callback functions @@ -128,6 +129,23 @@ void LLUrlAction::showLocationOnMap(std::string url)      }  } +void LLUrlAction::showParcelOnMap(std::string url) +{ +    LLSD path_array = LLURI(url).pathArray(); +    auto path_parts = path_array.size(); + +    if (path_parts < 3) // no parcel id +    { +        LL_WARNS() << "Global coordinates are missing in url: [" << url << "]" << LL_ENDL; +        return; +    } + +    LLVector3d parcel_pos = LLUrlEntryParcel::getParcelPos(LLUUID(LLURI::unescape(path_array[2]))); +    std::ostringstream pos; +    pos << parcel_pos.mdV[VX] << '/' << parcel_pos.mdV[VY] << '/' << parcel_pos.mdV[VZ]; +    executeSLURL("secondlife:///app/worldmap_global/" + pos.str()); +} +  void LLUrlAction::copyURLToClipboard(std::string url)  {      LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(url)); diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index ac9741a7ad..c960d61ca0 100644 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -63,6 +63,8 @@ public:      /// if the Url specifies an SL location, show it on a map      static void showLocationOnMap(std::string url); +    static void showParcelOnMap(std::string url); +      /// perform the appropriate action for left-clicking on a Url      static void clickAction(std::string url, bool trusted_content); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index bcd13b7f0b..59e8f47c8f 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -41,6 +41,7 @@  #include "lluicolortable.h"  #include "message.h"  #include "llexperiencecache.h" +#include "v3dmath.h"  #define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))" @@ -1084,6 +1085,7 @@ LLUUID  LLUrlEntryParcel::sSessionID(LLUUID::null);  LLHost  LLUrlEntryParcel::sRegionHost;  bool    LLUrlEntryParcel::sDisconnected(false);  std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers; +std::map<LLUUID, LLVector3d> LLUrlEntryParcel::sParcelPos;  ///  /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., @@ -1176,6 +1178,20 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data)              url_entry->onParcelInfoReceived(parcel_data.parcel_id.asString(), label);          }      } +    if (sParcelPos.find(parcel_data.parcel_id) == sParcelPos.end()) +    { +        sParcelPos[parcel_data.parcel_id] = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z); +    } +} + +// static +LLVector3d LLUrlEntryParcel::getParcelPos(const LLUUID& parcel_id) +{ +    if (sParcelPos.find(parcel_id) != sParcelPos.end()) +    { +        return sParcelPos[parcel_id]; +    } +    return LLVector3d();  }  // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 6e7d2fc80f..efa79c258d 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -41,6 +41,7 @@  #include <map>  class LLAvatarName; +class LLVector3d;  typedef boost::signals2::signal<void (const std::string& url,                                        const std::string& label, @@ -434,6 +435,8 @@ public:      // Processes parcel label and triggers notifying observers.      static void processParcelInfo(const LLParcelData& parcel_data); +    static LLVector3d getParcelPos(const LLUUID& parcel_id); +      // Next setters are used to update agent and viewer connection information      // upon events like user login, viewer disconnect and user changing region host.      // These setters are made public to be accessible from newview and should not be @@ -447,6 +450,7 @@ private:      static LLHost                       sRegionHost;      static bool                         sDisconnected;      static std::set<LLUrlEntryParcel*>  sParcelInfoObservers; +    static std::map<LLUUID, LLVector3d> sParcelPos;  };  /// diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index a306600f85..28639b9af0 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -670,7 +670,10 @@ LLWebRTCPeerConnectionInterface *LLWebRTCImpl::newPeerConnection()      peerConnection->init(this);      mPeerConnections.emplace_back(peerConnection); -    peerConnection->enableSenderTracks(!mMute); +    // Should it really start disabled? +    // Seems like something doesn't get the memo and senders need to be reset later +    // to remove the voice indicator from taskbar +    peerConnection->enableSenderTracks(false);      if (mPeerConnections.empty())      {          setRecording(true); @@ -704,7 +707,7 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn  LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() :      mWebRTCImpl(nullptr),      mPeerConnection(nullptr), -    mMute(true), +    mMute(MUTE_INITIAL),      mAnswerReceived(false)  {  } @@ -739,6 +742,19 @@ void LLWebRTCPeerConnectionImpl::terminate()                      }                  } +                // to remove 'Secondlife is recording' icon from taskbar +                // if user was speaking +                auto senders = mPeerConnection->GetSenders(); +                for (auto& sender : senders) +                { +                    auto track = sender->track(); +                    if (track) +                    { +                        track->set_enabled(false); +                    } +                } +                mPeerConnection->SetAudioRecording(false); +                  mPeerConnection->Close();                  if (mLocalStream)                  { @@ -828,6 +844,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti              audioOptions.auto_gain_control = true;              audioOptions.echo_cancellation = true;              audioOptions.noise_suppression = true; +            audioOptions.init_recording_on_send = false;              mLocalStream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream"); @@ -892,6 +909,7 @@ void LLWebRTCPeerConnectionImpl::enableSenderTracks(bool enable)          {              sender->track()->set_enabled(enable);          } +        mPeerConnection->SetAudioRecording(enable);      }  } @@ -932,9 +950,17 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp)  void LLWebRTCPeerConnectionImpl::setMute(bool mute)  { -    mMute = mute; +    EMicMuteState new_state = mute ? MUTE_MUTED : MUTE_UNMUTED; +    if (new_state == mMute) +    { +        return; // no change +    } +    bool force_reset = mMute == MUTE_INITIAL && mute; +    bool enable = !mute; +    mMute = new_state; +      mWebRTCImpl->PostSignalingTask( -        [this]() +        [this, force_reset, enable]()          {          if (mPeerConnection)          { @@ -946,16 +972,34 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)                  auto track = sender->track();                  if (track)                  { -                    track->set_enabled(!mMute); +                    if (force_reset) +                    { +                        // Force notify observers +                        // Was it disabled too early? +                        // Without this microphone icon in Win's taskbar will stay +                        track->set_enabled(true); +                    } +                    track->set_enabled(enable);                  }              } +            mPeerConnection->SetAudioRecording(enable);          }      });  }  void LLWebRTCPeerConnectionImpl::resetMute()  { -    setMute(mMute); +    switch(mMute) +    { +    case MUTE_MUTED: +         setMute(true); +         break; +    case MUTE_UNMUTED: +         setMute(false); +         break; +    default: +        break; +    }  }  void LLWebRTCPeerConnectionImpl::setReceiveVolume(float volume) diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index b93a1fdb01..b6294dbd4a 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -417,7 +417,12 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,      rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory; -    bool mMute; +    typedef enum { +        MUTE_INITIAL, +        MUTE_MUTED, +        MUTE_UNMUTED, +    } EMicMuteState; +    EMicMuteState mMute;      // signaling      std::vector<LLWebRTCSignalingObserver *>  mSignalingObserverList; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index af53b6fb3f..68b6de197a 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -76,6 +76,11 @@  #pragma comment(lib, "dxguid.lib") // needed for llurlentry test to build on some systems  #pragma comment(lib, "dinput8") +#pragma comment(lib, "UxTheme.lib") +#pragma comment(lib, "Dwmapi.lib") +#include <Uxtheme.h> +#include <dwmapi.h> // needed for DwmSetWindowAttribute to set window theme +  const S32   MAX_MESSAGE_PER_UPDATE = 20;  const S32   BITS_PER_PIXEL = 32;  const S32   MAX_NUM_RESOLUTIONS = 32; @@ -85,6 +90,10 @@ const F32   ICON_FLASH_TIME = 0.5f;  #define USER_DEFAULT_SCREEN_DPI 96 // Win7  #endif +#ifndef WM_DWMCOLORIZATIONCOLORCHANGED +#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 +#endif +  // Claim a couple unused GetMessage() message IDs  const UINT WM_DUMMY_(WM_USER + 0x0017);  const UINT WM_POST_FUNCTION_(WM_USER + 0x0018); @@ -104,6 +113,7 @@ static std::thread::id sMainThreadId;  LPWSTR gIconResource = IDI_APPLICATION; +LPWSTR gIconSmallResource = IDI_APPLICATION;  LPDIRECTINPUT8 gDirectInput8;  LLW32MsgCallback gAsyncMsgCallback = NULL; @@ -137,6 +147,17 @@ typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)(      _Out_ UINT *dpiX,      _Out_ UINT *dpiY); +typedef enum PREFERRED_APP_MODE +{ +    DEFAULT, +    ALLOW_DARK, +    FORCE_DARK, +    FORCE_LIGHT, +    MAX +} PREFERRED_APP_MODE; + +typedef PREFERRED_APP_MODE(WINAPI* fnSetPreferredAppMode)(PREFERRED_APP_MODE mode); +  //  // LLWindowWin32  // @@ -507,6 +528,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,      mFSAASamples = fsaa_samples;      mIconResource = gIconResource; +    mIconSmallResource = gIconSmallResource;      mOverrideAspectRatio = 0.f;      mNativeAspectRatio = 0.f;      mInputProcessingPaused = false; @@ -839,6 +861,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,      // Initialize (boot strap) the Language text input management,      // based on the system's (or user's) default settings.      allowLanguageTextInput(NULL, false); +    updateWindowTheme(); +    setCustomIcon();  } @@ -3007,6 +3031,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_                      WINDOW_IMP_POST(window_imp->mMouseVanish = true);                  }              } +            // Check if theme-related settings changed +            else if (l_param && (wcscmp((LPCWSTR)l_param, L"ImmersiveColorSet") == 0)) +            { +                WINDOW_IMP_POST(window_imp->updateWindowTheme()); +            } +        } +        break; + +        case WM_DWMCOLORIZATIONCOLORCHANGED: +        { +            WINDOW_IMP_POST(window_imp->updateWindowTheme());          }          break; @@ -4962,3 +4997,69 @@ void LLWindowWin32::updateWindowRect()              });      }  } + +bool LLWindowWin32::isSystemAppDarkMode() +{ +    HKEY  hKey; +    DWORD dwValue = 1; // Default to light theme +    DWORD dwSize  = sizeof(DWORD); + +    // Check registry for system theme preference +    LSTATUS ret_code = +        RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey); +    if (ERROR_SUCCESS == ret_code) +    { +        if (RegQueryValueExW(hKey, L"AppsUseLightTheme", NULL, NULL, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS) +        { +            // If AppsUseLightTheme is not found, check SystemUsesLightTheme +            dwSize = sizeof(DWORD); +            RegQueryValueExW(hKey, L"SystemUsesLightTheme", NULL, NULL, (LPBYTE)&dwValue, &dwSize); +        } +        RegCloseKey(hKey); +    } + +    // Return true if dark mode +    return dwValue == 0; +} + +void LLWindowWin32::updateWindowTheme() +{ +    bool use_dark_mode = isSystemAppDarkMode(); +    if (use_dark_mode == mCurrentDarkMode) +    { +        return; +    } +    mCurrentDarkMode = use_dark_mode; + +    HMODULE hUxTheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); +    if (hUxTheme) +    { +        auto SetPreferredAppMode = (fnSetPreferredAppMode)GetProcAddress(hUxTheme, "SetPreferredAppMode"); +        if (SetPreferredAppMode) +        { +            SetPreferredAppMode(use_dark_mode ? ALLOW_DARK : FORCE_LIGHT); +        } +        FreeLibrary(hUxTheme); +    } +    BOOL dark_mode(use_dark_mode); +    DwmSetWindowAttribute(mWindowHandle, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark_mode, sizeof(dark_mode)); + +    LL_INFOS("Window") << "Viewer window theme is set to " << (use_dark_mode ? "dark" : "light") << " mode" << LL_ENDL; +} + +void LLWindowWin32::setCustomIcon() +{ +        if (mWindowHandle) +        { +            HICON hDefaultIcon = LoadIcon(mhInstance, mIconResource); +            HICON hSmallIcon   = LoadIcon(mhInstance, mIconSmallResource); +            mWindowThread->post([=]() +                { +                    SendMessage(mWindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hDefaultIcon); +                    SendMessage(mWindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hSmallIcon); + +                    SetClassLongPtr(mWindowHandle, GCLP_HICON, (LONG_PTR)hDefaultIcon); +                    SetClassLongPtr(mWindowHandle, GCLP_HICONSM, (LONG_PTR)hSmallIcon); +                }); +        } +} diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 561f07d388..7196706f87 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -214,6 +214,7 @@ protected:      bool        mCustomGammaSet;      LPWSTR      mIconResource; +    LPWSTR      mIconSmallResource;      bool        mInputProcessingPaused;      // The following variables are for Language Text Input control. @@ -246,6 +247,11 @@ protected:      RECT mRect;      RECT mClientRect; +    void updateWindowTheme(); +    bool isSystemAppDarkMode(); +    void setCustomIcon(); +    bool mCurrentDarkMode { false }; +      struct LLWindowWin32Thread;      LLWindowWin32Thread* mWindowThread = nullptr;      LLThreadSafeQueue<std::function<void()>> mFunctionQueue; @@ -281,6 +287,7 @@ private:  extern LLW32MsgCallback gAsyncMsgCallback;  extern LPWSTR gIconResource; +extern LPWSTR gIconSmallResource;  S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 type); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 481db3d108..759a40fc08 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -15,6 +15,9 @@ include(CMakeCopyIfDifferent)  include(CubemapToEquirectangularJS)  include(DBusGlib)  include(DragDrop) +if (USE_DISCORD) +  include(Discord) +endif ()  include(EXPAT)  include(Hunspell)  include(JPEGEncoderBasic) @@ -1568,6 +1571,7 @@ if (WINDOWS)          res-sdl/ll_icon.BMP          res/ll_icon.BMP          res/ll_icon.ico +        res/ll_icon_small.ico          res/resource.h          res/toolpickobject.cur          res/toolpickobject2.cur @@ -1783,6 +1787,12 @@ if (WINDOWS)                 )      endif (ADDRESS_SIZE EQUAL 64) +    if (TARGET ll::discord_sdk) +        list(APPEND COPY_INPUT_DEPENDENCIES +             ${SHARED_LIB_STAGING_DIR}/discord_partner_sdk.dll +             ) +    endif () +      if (TARGET ll::openal)        list(APPEND COPY_INPUT_DEPENDENCIES             ${SHARED_LIB_STAGING_DIR}/OpenAL32.dll @@ -1799,6 +1809,7 @@ if (WINDOWS)          --arch=${ARCH}          --artwork=${ARTWORK_DIR}          "--bugsplat=${BUGSPLAT_DB}" +        "--discord=${USE_DISCORD}"          "--openal=${USE_OPENAL}"          "--tracy=${USE_TRACY}"          --build=${CMAKE_CURRENT_BINARY_DIR} @@ -1837,6 +1848,7 @@ if (WINDOWS)              --arch=${ARCH}              --artwork=${ARTWORK_DIR}              "--bugsplat=${BUGSPLAT_DB}" +            "--discord=${USE_DISCORD}"              "--openal=${USE_OPENAL}"              "--tracy=${USE_TRACY}"              --build=${CMAKE_CURRENT_BINARY_DIR} @@ -1901,6 +1913,7 @@ if (WINDOWS)                --arch=${ARCH}                --artwork=${ARTWORK_DIR}                "--bugsplat=${BUGSPLAT_DB}" +              "--discord=${USE_DISCORD}"                "--openal=${USE_OPENAL}"                "--tracy=${USE_TRACY}"                --build=${CMAKE_CURRENT_BINARY_DIR} @@ -1996,6 +2009,10 @@ target_link_libraries(${VIEWER_BINARY_NAME}          ll::openxr          ) +if (USE_DISCORD) +   target_link_libraries(${VIEWER_BINARY_NAME} ll::discord_sdk ) +endif () +  if( TARGET ll::intel_memops )     target_link_libraries(${VIEWER_BINARY_NAME} ll::intel_memops )  endif() @@ -2052,6 +2069,7 @@ if (LINUX)          --arch=${ARCH}          --artwork=${ARTWORK_DIR}          "--bugsplat=${BUGSPLAT_DB}" +        "--discord=${USE_DISCORD}"          "--openal=${USE_OPENAL}"          "--tracy=${USE_TRACY}"          --build=${CMAKE_CURRENT_BINARY_DIR} @@ -2080,6 +2098,7 @@ if (LINUX)        --arch=${ARCH}        --artwork=${ARTWORK_DIR}        "--bugsplat=${BUGSPLAT_DB}" +      "--discord=${USE_DISCORD}"        "--openal=${USE_OPENAL}"        "--tracy=${USE_TRACY}"        --build=${CMAKE_CURRENT_BINARY_DIR} @@ -2156,6 +2175,7 @@ if (DARWIN)        --arch=${ARCH}        --artwork=${ARTWORK_DIR}        "--bugsplat=${BUGSPLAT_DB}" +      "--discord=${USE_DISCORD}"        "--openal=${USE_OPENAL}"        "--tracy=${USE_TRACY}"        --build=${CMAKE_CURRENT_BINARY_DIR} @@ -2191,6 +2211,7 @@ if (DARWIN)                --arch=${ARCH}                --artwork=${ARTWORK_DIR}                "--bugsplat=${BUGSPLAT_DB}" +              "--discord=${USE_DISCORD}"                "--openal=${USE_OPENAL}"                "--tracy=${USE_TRACY}"                --build=${CMAKE_CURRENT_BINARY_DIR} diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5b5551dbe0..0614be8bf6 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1150,6 +1150,39 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>EnableDiscord</key> +    <map> +      <key>Comment</key> +      <string>When set, connect to Discord to enable Rich Presence</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowDiscordActivityDetails</key> +    <map> +      <key>Comment</key> +      <string>When set, show avatar name on Discord Rich Presence</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowDiscordActivityState</key> +    <map> +      <key>Comment</key> +      <string>When set, show location on Discord Rich Presence</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>EnableDiskCacheDebugInfo</key>      <map>        <key>Comment</key> @@ -1164,13 +1197,13 @@      <key>DiskCachePercentOfTotal</key>      <map>        <key>Comment</key> -      <string>The percent of total cache size (defined by CacheSize) to use for the disk cache</string> +      <string>The percent of total cache size (defined by CacheSize) to use for the disk cache (ex: asset storage, excludes textures)</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key>        <string>F32</string>        <key>Value</key> -      <real>40.0</real> +      <real>35.0</real>      </map>      <key>DiskCacheDirName</key>      <map> @@ -1214,7 +1247,7 @@        <key>Type</key>        <string>U32</string>        <key>Value</key> -      <integer>4096</integer> +      <integer>6144</integer>      </map>      <key>CacheValidateCounter</key>      <map> @@ -9606,6 +9639,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>ObscureBalanceInStatusBar</key> +    <map> +        <key>Comment</key> +        <string>If true, balance will be shows as '*'</string> +        <key>Persist</key> +        <integer>1</integer> +        <key>Type</key> +        <string>Boolean</string> +        <key>Value</key> +        <integer>0</integer> +    </map>      <key>RenderUIBuffer</key>      <map>        <key>Comment</key> @@ -13753,7 +13797,7 @@      <key>FullScreen</key>      <map>        <key>Comment</key> -      <string>run a fullscreen session</string> +      <string>Run a fullscreen session. MacOS not supported</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -16245,5 +16289,49 @@        <key>Value</key>        <integer>31</integer>      </map> +    <key>EnableSelectionHints</key> +    <map> +      <key>Comment</key> +      <string>Whether or not to send editing hints to animate the arm when editing an object.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    <key>EnableLookAtTarget</key> +    <map> +      <key>Comment</key> +      <string>Whether or not to animate the avatar head and send look at targets when moving the cursor or focusing on objects</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    <key>LimitLookAtTarget</key> +    <map> +      <key>Comment</key> +      <string>Whether or not to clamp the look at targets around the avatar head before sending</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>LimitLookAtTargetDistance</key> +    <map> +      <key>Comment</key> +      <string>Distance to limit look at target to</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>2</integer> +    </map>  </map>  </llsd> diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index cd4222dddf..25f5cbd78f 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1094,12 +1094,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it      {          gAgentAvatarp->setCompositeUpdatesEnabled(true); -        // If we have not yet declouded, we may want to use +        // If we have not yet loaded core parts, we may want to use          // baked texture UUIDs sent from the first objectUpdate message -        // don't overwrite these. If we have already declouded, we've saved -        // these ids as the last known good textures and can invalidate without -        // re-clouding. -        if (!gAgentAvatarp->getIsCloud()) +        // don't overwrite these. If we have parts already, we've saved +        // these texture ids as the last known good textures and can +        // invalidate without having to recloud avatar. +        if (!gAgentAvatarp->getHasMissingParts())          {              gAgentAvatarp->invalidateAll();          } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e9d455ae53..8a17ccfeef 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -856,7 +856,7 @@ void LLWearableHoldingPattern::checkMissingWearables()              // was requested but none was found, create a default asset as a replacement.              // In all other cases, don't do anything.              // For critical types (shape/hair/skin/eyes), this will keep the avatar as a cloud -            // due to logic in LLVOAvatarSelf::getIsCloud(). +            // due to logic in LLVOAvatarSelf::getHasMissingParts().              // For non-critical types (tatoo, socks, etc.) the wearable will just be missing.              (requested_by_type[type] > 0) &&              ((type == LLWearableType::WT_PANTS) || (type == LLWearableType::WT_SHIRT) || (type == LLWearableType::WT_SKIRT))) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 35fdc18839..28b40543e9 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -268,6 +268,16 @@ using namespace LL;  #include "glib.h"  #endif // (LL_LINUX) && LL_GTK +#ifdef LL_DISCORD +#define DISCORDPP_IMPLEMENTATION +#include <discordpp.h> +static std::shared_ptr<discordpp::Client> gDiscordClient; +static uint64_t gDiscordTimestampsStart; +static std::string gDiscordActivityDetails; +static int32_t gDiscordPartyCurrentSize; +static int32_t gDiscordPartyMaxSize; +#endif +  static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);  ////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor @@ -1319,6 +1329,13 @@ bool LLAppViewer::frame()  bool LLAppViewer::doFrame()  { +#ifdef LL_DISCORD +    { +        LL_PROFILE_ZONE_NAMED("discord_callbacks"); +        discordpp::RunCallbacks(); +    } +#endif +      LL_RECORD_BLOCK_TIME(FTM_FRAME);      {      // and now adjust the visuals from previous frame. @@ -3093,7 +3110,15 @@ bool LLAppViewer::initWindow()          .height(gSavedSettings.getU32("WindowHeight"))          .min_width(gSavedSettings.getU32("MinWindowWidth"))          .min_height(gSavedSettings.getU32("MinWindowHeight")) +#ifdef LL_DARWIN +        // Setting it to true causes black screen with no UI displayed. +        // Given that it's a DEBUG settings and application goes fullscreen +        // on mac simply by expanding it, it was decided to not support/use +        // this setting on mac. +        .fullscreen(false) +#else // LL_DARWIN          .fullscreen(gSavedSettings.getBOOL("FullScreen")) +#endif          .ignore_pixel_depth(ignorePixelDepth)          .first_run(mIsFirstRun); @@ -4279,8 +4304,8 @@ bool LLAppViewer::initCache()      const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");      const U32 MB = 1024 * 1024; -    const uintmax_t MIN_CACHE_SIZE = 256 * MB; -    const uintmax_t MAX_CACHE_SIZE = 9984ll * MB; +    const uintmax_t MIN_CACHE_SIZE = 896 * MB; +    const uintmax_t MAX_CACHE_SIZE = 32768ll * MB;      const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB;      const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);      const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); @@ -5881,3 +5906,180 @@ void LLAppViewer::metricsSend(bool enable_reporting)      gViewerAssetStats->restart();  } +#ifdef LL_DISCORD + +void LLAppViewer::initDiscordSocial() +{ +    gDiscordPartyCurrentSize = 1; +    gDiscordPartyMaxSize = 0; +    gDiscordTimestampsStart = time(nullptr); +    gDiscordClient = std::make_shared<discordpp::Client>(); +    gDiscordClient->SetStatusChangedCallback([](discordpp::Client::Status status, discordpp::Client::Error, int32_t) { +        if (status == discordpp::Client::Status::Ready) +        { +            updateDiscordActivity(); +        } +    }); +    if (gSavedSettings.getBOOL("EnableDiscord")) +    { +        auto credential = gSecAPIHandler->loadCredential("Discord"); +        if (credential.notNull()) +        { +            gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) { +                if (result.Successful()) +                    gDiscordClient->Connect(); +                else +                    LL_WARNS("Discord") << result.Error() << LL_ENDL; +            }); +        } +        else +        { +            LL_WARNS("Discord") << "Integration was enabled, but no credentials. Disabling integration." << LL_ENDL; +            gSavedSettings.setBOOL("EnableDiscord", false); +        } +    } +} + +void LLAppViewer::toggleDiscordIntegration(const LLSD& value) +{ +    static const uint64_t APPLICATION_ID = 1394782217405862001; +    if (value.asBoolean()) +    { +        discordpp::AuthorizationArgs args{}; +        args.SetClientId(APPLICATION_ID); +        args.SetScopes(discordpp::Client::GetDefaultPresenceScopes()); +        auto codeVerifier = gDiscordClient->CreateAuthorizationCodeVerifier(); +        args.SetCodeChallenge(codeVerifier.Challenge()); +        gDiscordClient->Authorize(args, [codeVerifier](auto result, auto code, auto redirectUri) { +            if (result.Successful()) +            { +                gDiscordClient->GetToken(APPLICATION_ID, code, codeVerifier.Verifier(), redirectUri, [](discordpp::ClientResult result, std::string accessToken, std::string, discordpp::AuthorizationTokenType, int32_t, std::string) { +                    if (result.Successful()) +                    { +                        gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, accessToken, [accessToken](discordpp::ClientResult result) { +                            if (result.Successful()) +                            { +                                LLSD authenticator = LLSD::emptyMap(); +                                authenticator["token"] = accessToken; +                                gSecAPIHandler->saveCredential(gSecAPIHandler->createCredential("Discord", LLSD::emptyMap(), authenticator), true); +                                gDiscordClient->Connect(); +                            } +                            else +                            { +                                LL_WARNS("Discord") << result.Error() << LL_ENDL; +                            } +                        }); +                    } +                    else +                    { +                        LL_WARNS("Discord") << result.Error() << LL_ENDL; +                    } +                }); +            } +            else +            { +                LL_WARNS("Discord") << result.Error() << LL_ENDL; +                gSavedSettings.setBOOL("EnableDiscord", false); +            } +        }); +    } +    else +    { +        gDiscordClient->Disconnect(); +        auto credential = gSecAPIHandler->loadCredential("Discord"); +        if (credential.notNull()) +        { +            gDiscordClient->RevokeToken(APPLICATION_ID, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) { +                if (result.Successful()) +                    LL_INFOS("Discord") << "Access token successfully revoked." << LL_ENDL; +                else +                    LL_WARNS("Discord") << "No access token to revoke." << LL_ENDL; +            }); +            auto cred = new LLCredential("Discord"); +            gSecAPIHandler->deleteCredential(cred); +        } +        else +        { +            LL_WARNS("Discord") << "Credentials are already nonexistent." << LL_ENDL; +        } +    } +} + +void LLAppViewer::updateDiscordActivity() +{ +    LL_PROFILE_ZONE_SCOPED; +    discordpp::Activity activity; +    activity.SetType(discordpp::ActivityTypes::Playing); +    discordpp::ActivityTimestamps timestamps; +    timestamps.SetStart(gDiscordTimestampsStart); +    activity.SetTimestamps(timestamps); + +    if (gAgent.getID() == LLUUID::null) +    { +        gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {}); +        return; +    } + +    static LLCachedControl<bool> show_details(gSavedSettings, "ShowDiscordActivityDetails", false); +    if (show_details) +    { +        if (gDiscordActivityDetails.empty()) +        { +            LLAvatarName av_name; +            LLAvatarNameCache::get(gAgent.getID(), &av_name); +            gDiscordActivityDetails = av_name.getUserName(); +            auto displayName = av_name.getDisplayName(); +            if (gDiscordActivityDetails != displayName) +                gDiscordActivityDetails = displayName + " (" + gDiscordActivityDetails + ")"; +        } +        activity.SetDetails(gDiscordActivityDetails); +    } + +    static LLCachedControl<bool> show_state(gSavedSettings, "ShowDiscordActivityState", false); +    if (show_state) +    { +        auto agent_pos_region = gAgent.getPositionAgent(); +        S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f); +        S32 pos_y = S32(agent_pos_region.mV[VY] + 0.5f); +        S32 pos_z = S32(agent_pos_region.mV[VZ] + 0.5f); +        F32 velocity_mag_sq = gAgent.getVelocity().magVecSquared(); +        const F32 FLY_CUTOFF = 6.f; +        const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF; +        const F32 WALK_CUTOFF = 1.5f; +        const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF; +        if (velocity_mag_sq > FLY_CUTOFF_SQ) +        { +            pos_x -= pos_x % 4; +            pos_y -= pos_y % 4; +        } +        else if (velocity_mag_sq > WALK_CUTOFF_SQ) +        { +            pos_x -= pos_x % 2; +            pos_y -= pos_y % 2; +        } +        auto location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z); +        activity.SetState(location); + +        discordpp::ActivityParty party; +        party.SetId(location); +        party.SetCurrentSize(gDiscordPartyCurrentSize); +        party.SetMaxSize(gDiscordPartyMaxSize); +        activity.SetParty(party); +    } + +    gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {}); +} + +void LLAppViewer::updateDiscordPartyCurrentSize(int32_t size) +{ +    gDiscordPartyCurrentSize = size; +    updateDiscordActivity(); +} + +void LLAppViewer::updateDiscordPartyMaxSize(int32_t size) +{ +    gDiscordPartyMaxSize = size; +    updateDiscordActivity(); +} + +#endif diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index bafe952659..14e96afe94 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -251,6 +251,14 @@ public:      // Note: mQuitRequested can be aborted by user.      void outOfMemorySoftQuit(); +#ifdef LL_DISCORD +    static void initDiscordSocial(); +    static void toggleDiscordIntegration(const LLSD& value); +    static void updateDiscordActivity(); +    static void updateDiscordPartyCurrentSize(int32_t size); +    static void updateDiscordPartyMaxSize(int32_t size); +#endif +  protected:      virtual bool initWindow(); // Initialize the viewer's window.      virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 6274933586..8477bd3044 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -448,6 +448,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,      // *FIX: global      gIconResource = MAKEINTRESOURCE(IDI_LL_ICON); +    gIconSmallResource = MAKEINTRESOURCE(IDI_LL_ICON_SMALL);      LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(ll_convert_wide_to_string(pCmdLine).c_str()); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 989e1d8d04..49e557a6cb 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -32,6 +32,7 @@  #include "llimagetga.h"  #include "llimagejpeg.h"  #include "llimagepng.h" +#include "llimagej2c.h"  #include "llagent.h"  #include "llagentbenefits.h" @@ -43,6 +44,10 @@  #include "llrender.h"  #include "llface.h"  #include "llfocusmgr.h" +#include "llfilesystem.h" +#include "llfloaterperms.h" +#include "llnotificationsutil.h" +#include "llstatusbar.h"    // can_afford_transaction()  #include "lltextbox.h"  #include "lltoolmgr.h"  #include "llui.h" @@ -52,6 +57,7 @@  #include "llvoavatar.h"  #include "pipeline.h"  #include "lluictrlfactory.h" +#include "llviewermenufile.h"   // upload_new_resource()  #include "llviewershadermgr.h"  #include "llviewertexturelist.h"  #include "llstring.h" @@ -140,7 +146,7 @@ bool LLFloaterImagePreview::postBuild()          }      } -    getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); +    getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterImagePreview::onBtnOK, this));      return true;  } @@ -244,6 +250,59 @@ void LLFloaterImagePreview::clearAllPreviewTextures()  }  //----------------------------------------------------------------------------- +// onBtnOK() +//----------------------------------------------------------------------------- +void LLFloaterImagePreview::onBtnOK() +{ +    getChildView("ok_btn")->setEnabled(false); // don't allow inadvertent extra uploads + +    S32 expected_upload_cost = getExpectedUploadCost(); +    if (can_afford_transaction(expected_upload_cost)) +    { +        LL_INFOS() << "saving texture: " << mRawImagep->getWidth() << "x" << mRawImagep->getHeight() << LL_ENDL; +        // gen a new uuid for this asset +        LLTransactionID tid; +        tid.generate(); +        LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + +        LLPointer<LLImageJ2C> formatted = new LLImageJ2C; + +        if (formatted->encode(mRawImagep, 0.0f)) +        { +            LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE); +            fmt_file.write(formatted->getData(), formatted->getDataSize()); + +            LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo( +                tid, LLAssetType::AT_TEXTURE, +                getChild<LLUICtrl>("name_form")->getValue().asString(), +                getChild<LLUICtrl>("description_form")->getValue().asString(), +                0, +                LLFolderType::FT_NONE, LLInventoryType::IT_NONE, +                LLFloaterPerms::getNextOwnerPerms("Uploads"), +                LLFloaterPerms::getGroupPerms("Uploads"), +                LLFloaterPerms::getEveryonePerms("Uploads"), +                expected_upload_cost +            )); + +            upload_new_resource(assetUploadInfo); +        } +        else +        { +            LLNotificationsUtil::add("ErrorEncodingImage"); +            LL_WARNS() << "Error encoding image" << LL_ENDL; +        } +    } +    else +    { +        LLSD args; +        args["COST"] = llformat("%d", expected_upload_cost); +        LLNotificationsUtil::add("ErrorCannotAffordUpload", args); +    } + +    closeFloater(false); +} + +//-----------------------------------------------------------------------------  // draw()  //-----------------------------------------------------------------------------  void LLFloaterImagePreview::draw() @@ -364,19 +423,6 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename)          return false;      } -    S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); -    S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); - -    if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height)) -    { -        LLStringUtil::format_map_t args; -        args["WIDTH"] = llformat("%d", max_width); -        args["HEIGHT"] = llformat("%d", max_height); - -        mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); -        return false; -    } -      // Load the image      LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);      if (image.isNull()) @@ -399,6 +445,46 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename)          image->setLastError("Image files with less than 3 or more than 4 components are not supported.");          return false;      } +    // Downscale images to fit the max_texture_dimensions_* +    S32 max_width  = gSavedSettings.getS32("max_texture_dimension_X"); +    S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); + +    S32 orig_width  = raw_image->getWidth(); +    S32 orig_height = raw_image->getHeight(); + +    if (orig_width > max_width || orig_height > max_height) +    { +        // Calculate scale factors +        F32 width_scale  = (F32)max_width / (F32)orig_width; +        F32 height_scale = (F32)max_height / (F32)orig_height; +        F32 scale        = llmin(width_scale, height_scale); + +        // Calculate new dimensions, preserving aspect ratio +        S32 new_width  = LLImageRaw::contractDimToPowerOfTwo( +            llclamp((S32)llroundf(orig_width * scale), 4, max_width) +        ); +        S32 new_height = LLImageRaw::contractDimToPowerOfTwo( +            llclamp((S32)llroundf(orig_height * scale), 4, max_height) +        ); + +        if (!raw_image->scale(new_width, new_height)) +        { +            LL_WARNS() << "Failed to scale image from " +                       << orig_width << "x" << orig_height +                       << " to " << new_width << "x" << new_height << LL_ENDL; +            return false; +        } + +        // Inform the resident about the resized image +        LLSD subs; +        subs["[ORIGINAL_WIDTH]"]  = orig_width; +        subs["[ORIGINAL_HEIGHT]"] = orig_height; +        subs["[NEW_WIDTH]"]       = new_width; +        subs["[NEW_HEIGHT]"]      = new_height; +        subs["[MAX_WIDTH]"]       = max_width; +        subs["[MAX_HEIGHT]"]      = max_height; +        LLNotificationsUtil::add("ImageUploadResized", subs); +    }      raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);      mRawImagep = raw_image; diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index ed395722de..0ebb96a768 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -126,6 +126,8 @@ public:      void clearAllPreviewTextures(); +    void onBtnOK(); +  protected:      static void     onPreviewTypeCommit(LLUICtrl*,void*);      void            draw() override; diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index 2496887c9d..81eab52e6c 100644 --- a/indra/newview/llfloatermediasettings.cpp +++ b/indra/newview/llfloatermediasettings.cpp @@ -180,8 +180,15 @@ void LLFloaterMediaSettings::onClose(bool app_quitting)  ////////////////////////////////////////////////////////////////////////////////  //static -void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable ) +void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable, bool has_media_info, bool multiple_media, bool multiple_valid_media)  { +    if (!sInstance) +    { +        return; +    } +    sInstance->mIdenticalHasMediaInfo = has_media_info; +    sInstance->mMultipleMedia = multiple_media; +    sInstance->mMultipleValidMedia = multiple_valid_media;      if (sInstance->hasFocus()) return;      // Clear values diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h index 38730ddc98..7ed7ab246f 100644 --- a/indra/newview/llfloatermediasettings.h +++ b/indra/newview/llfloatermediasettings.h @@ -48,7 +48,7 @@ public:      static LLFloaterMediaSettings* getInstance();      static bool instanceExists();      static void apply(); -    static void initValues( const LLSD& media_settings , bool editable); +    static void initValues( const LLSD& media_settings , bool editable, bool has_media_info, bool multiple_media, bool multiple_valid_media);      static void clearValues( bool editable);      LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;}; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index fdac390e8a..c84728248c 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -366,6 +366,11 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)      mCommitCallbackRegistrar.add("Pref.ClearLog",               boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));      mCommitCallbackRegistrar.add("Pref.DeleteTranscripts",      boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));      mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering +#ifdef LL_DISCORD +    gSavedSettings.getControl("EnableDiscord")->getCommitSignal()->connect(boost::bind(&LLAppViewer::toggleDiscordIntegration, _2)); +    gSavedSettings.getControl("ShowDiscordActivityDetails")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity)); +    gSavedSettings.getControl("ShowDiscordActivityState")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity)); +#endif  }  void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type ) @@ -523,6 +528,10 @@ bool LLFloaterPreference::postBuild()          getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);      } +#ifndef LL_DISCORD +    getChild<LLTabContainer>("privacy_tab_container")->childDisable("privacy_preferences_discord"); +#endif +      return true;  } diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 8cc01f6dc6..01108b5cfa 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -207,14 +207,14 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)          mSettingNameText->setToolTip(controlp->getName());          mComment->setVisible(true); -        std::string old_text = mComment->getText();          std::string new_text = controlp->getComment();          // Don't setText if not nessesary, it will reset scroll          // This is a debug UI that reads from xml, there might          // be use cases where comment changes, but not the name -        if (old_text != new_text) +        if (mOldText != new_text)          {              mComment->setText(controlp->getComment()); +            mOldText = new_text;          }          mValSpinner1->setMaxValue(F32_MAX); @@ -467,6 +467,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)            }            default:              mComment->setText(std::string("unknown")); +            mOldText = "unknown";              break;          }      } diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h index b813cf4a74..8781cd3b67 100644 --- a/indra/newview/llfloatersettingsdebug.h +++ b/indra/newview/llfloatersettingsdebug.h @@ -82,6 +82,7 @@ protected:      LLColorSwatchCtrl* mColorSwatch = nullptr;      std::string mSearchFilter; +    std::string mOldText;  };  #endif //LLFLOATERDEBUGSETTINGS_H diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 6e6eaa3a20..03979edbc1 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -169,6 +169,52 @@ public:  };  LLWorldMapHandler gWorldMapHandler; +// handle secondlife:///app/worldmap_global/{GLOBAL_COORDS} URLs +class LLWorldMapGlobalHandler : public LLCommandHandler +{ +public: +    LLWorldMapGlobalHandler() : LLCommandHandler("worldmap_global", UNTRUSTED_THROTTLE) +    {} + +    virtual bool canHandleUntrusted( +        const LLSD& params, +        const LLSD& query_map, +        LLMediaCtrl* web, +        const std::string& nav_type) +    { +        if (nav_type == NAV_TYPE_CLICKED +            || nav_type == NAV_TYPE_EXTERNAL) +        { +            // NAV_TYPE_EXTERNAL will be throttled +            return true; +        } + +        return false; +    } + +    bool handle(const LLSD& params, +                const LLSD& query_map, +                const std::string& grid, +                LLMediaCtrl* web) +    { +        if (params.size() < 3) +        { +            LL_WARNS() << "Correct global coordinates are not provided." << LL_ENDL; +            return true; +        } + +        LLVector3d parcel_global_pos = LLVector3d(params[0].asInteger(), params[1].asInteger(), params[2].asInteger()); +        LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); +        if (!parcel_global_pos.isExactlyZero() && worldmap_instance) +        { +            worldmap_instance->trackLocation(parcel_global_pos); +            LLFloaterReg::showInstance("world_map", "center"); +        } +        return true; +    } +}; +LLWorldMapGlobalHandler gWorldMapGlobalHandler; +  // SocialMap handler secondlife:///app/maptrackavatar/id  class LLMapTrackAvatarHandler : public LLCommandHandler  { diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index d0d2ee191a..776d2dd31e 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -37,6 +37,7 @@  #include "lldrawable.h"  #include "llviewerobjectlist.h"  #include "llviewercontrol.h" +#include "llvoavatarself.h"  #include "llrendersphere.h"  #include "llselectmgr.h"  #include "llglheaders.h" @@ -397,6 +398,21 @@ bool LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec          return false;      } +    static LLCachedControl<bool> enable_lookat_hints(gSavedSettings, "EnableLookAtTarget", true); +    if (!enable_lookat_hints) +    { +        // Clear the effect so it doesn't linger around if it gets disabled +        if (mTargetType != LOOKAT_TARGET_IDLE) +        { +            mTargetObject = gAgentAvatarp; +            mTargetType = LOOKAT_TARGET_IDLE; +            mTargetOffsetGlobal.set(2.f, 0.f, 0.f); +            setDuration(3.f); +            setNeedsSendToSim(true); +        } +        return false; +    } +      if (target_type >= LOOKAT_NUM_TARGETS)      {          LL_WARNS() << "Bad target_type " << (int)target_type << " - ignoring." << LL_ENDL; @@ -409,6 +425,29 @@ bool LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec          return false;      } +    static LLCachedControl<bool> limit_lookat_hints(gSavedSettings, "LimitLookAtTarget", true); +    // Don't affect the look at if object is gAgentAvatarp (cursor head follow) +    if (limit_lookat_hints && object != gAgentAvatarp) +    { +        // If it is a object +        if (object) +        { +            position += object->getRenderPosition(); +            object = NULL; +        } + +        LLVector3 agentHeadPosition = gAgentAvatarp->mHeadp->getWorldPosition(); +        float dist = (float)dist_vec(agentHeadPosition, position); + +        static LLCachedControl<F32> limit_lookat_hints_distance(gSavedSettings, "LimitLookAtTargetDistance", 2.0f); +        if (dist > limit_lookat_hints_distance) +        { +            LLVector3 headOffset = position - agentHeadPosition; +            headOffset *= limit_lookat_hints_distance / dist; +            position.setVec(agentHeadPosition + headOffset); +        } +    } +      F32 current_time  = mTimer.getElapsedTimeF32();      // type of lookat behavior or target object has changed diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp index eeb38cd6aa..c600010f6b 100644 --- a/indra/newview/llhudeffectpointat.cpp +++ b/indra/newview/llhudeffectpointat.cpp @@ -34,6 +34,7 @@  #include "llagent.h"  #include "llagentcamera.h"  #include "lldrawable.h" +#include "llviewercontrol.h"  #include "llviewerobjectlist.h"  #include "llvoavatar.h"  #include "message.h" @@ -226,6 +227,19 @@ bool LLHUDEffectPointAt::setPointAt(EPointAtType target_type, LLViewerObject *ob          return false;      } +    static LLCachedControl<bool> enable_selection_hints(gSavedSettings, "EnableSelectionHints", true); +    if (!enable_selection_hints) +    { +        // Clear the effect so it doesn't linger around if it gets disabled +        if (mTargetType != POINTAT_TARGET_NONE) +        { +            clearPointAtTarget(); +            setDuration(1.f); +            setNeedsSendToSim(true); +        } +        return false; +    } +      if (target_type >= POINTAT_NUM_TARGETS)      {          LL_WARNS() << "Bad target_type " << (int)target_type << " - ignoring." << LL_ENDL; diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 4c02511268..7cd0171a37 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1520,10 +1520,10 @@ void LLIMProcessing::requestOfflineMessages()      if (!requested          && gMessageSystem          && !gDisconnected -        && LLMuteList::getInstance()->isLoaded()          && isAgentAvatarValid()          && gAgent.getRegion() -        && gAgent.getRegion()->capabilitiesReceived()) +        && gAgent.getRegion()->capabilitiesReceived() +        && (LLMuteList::getInstance()->isLoaded() || LLMuteList::getInstance()->getLoadFailed()))      {          std::string cap_url = gAgent.getRegionCapability("ReadOfflineMsgs"); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 142a3dac39..eb9e054600 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2362,7 +2362,13 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p      LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));      if (volume->unpackVolumeFaces(data, data_size))      { -        if (volume->getNumFaces() > 0) +        // Use LLVolume::getNumVolumeFaces() here and not LLVolume::getNumFaces(), +        // because setMeshAssetLoaded() has not yet been called for this volume +        // (it is set later in LLMeshRepository::notifyMeshLoaded()), and +        // getNumFaces() would return the number of faces in the LLProfile +        // instead. HB +        S32 num_faces = volume->getNumVolumeFaces(); +        if (num_faces > 0)          {              // if we have a valid SkinInfo, cache per-joint bounding boxes for this LOD              LLPointer<LLMeshSkinInfo> skin_info = nullptr; @@ -2376,7 +2382,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p              }              if (skin_info.notNull() && isAgentAvatarValid())              { -                for (S32 i = 0; i < volume->getNumFaces(); ++i) +                for (S32 i = 0; i < num_faces; ++i)                  {                      // NOTE: no need to lock gAgentAvatarp as the state being checked is not changed after initialization                      LLVolumeFace& face = volume->getVolumeFace(i); diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 2d51acc063..f6d635f51f 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -154,7 +154,8 @@ std::string LLMute::getDisplayType() const  // LLMuteList()  //-----------------------------------------------------------------------------  LLMuteList::LLMuteList() : -    mIsLoaded(false) +    mLoadState(ML_INITIAL), +    mRequestStartTime(0.f)  {      gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList); @@ -209,6 +210,23 @@ bool LLMuteList::isLinden(const std::string& name)      return last_name == "linden";  } +bool LLMuteList::getLoadFailed() const +{ +    if (mLoadState == ML_FAILED) +    { +        return true; +    } +    if (mLoadState == ML_REQUESTED) +    { +        constexpr F64 WAIT_SECONDS = 30; +        if (mRequestStartTime + WAIT_SECONDS < LLTimer::getTotalSeconds()) +        { +            return true; +        } +    } +    return false; +} +  static LLVOAvatar* find_avatar(const LLUUID& id)  {      LLViewerObject *obj = gObjectList.findObject(id); @@ -371,11 +389,14 @@ void LLMuteList::updateAdd(const LLMute& mute)      msg->addU32("MuteFlags", mute.mFlags);      gAgent.sendReliableMessage(); -    if (!mIsLoaded) +    if (!isLoaded())      {          LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL;      } -    mIsLoaded = true; // why is this here? -MG +    // Based of logs and testing, if file doesn't exist server side, +    // viewer will not receive any callback and won't know to set +    // ML_LOADED. As a workaround, set it regardless of current state. +    mLoadState = ML_LOADED;  } @@ -564,6 +585,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)      if(!filename.size())      {          LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL; +        mLoadState = ML_FAILED;          return false;      } @@ -571,6 +593,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)      if (!fp)      {          LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL; +        mLoadState = ML_FAILED;          return false;      } @@ -730,13 +753,17 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)      if (gDisconnected)      {          LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL; +        mLoadState = ML_FAILED;          return;      }      if (!gAgent.getRegion())      {          LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL; +        mLoadState = ML_FAILED;          return;      } +    mLoadState = ML_REQUESTED; +    mRequestStartTime = LLTimer::getElapsedSeconds();      // Double amount of retries due to this request happening during busy stage      // Ideally this should be turned into a capability      gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, true, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL); @@ -749,7 +776,7 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)  void LLMuteList::cache(const LLUUID& agent_id)  {      // Write to disk even if empty. -    if(mIsLoaded) +    if(isLoaded())      {          std::string agent_id_string;          std::string filename; @@ -777,6 +804,13 @@ void LLMuteList::processMuteListUpdate(LLMessageSystem* msg, void**)      msg->getStringFast(_PREHASH_MuteData, _PREHASH_Filename, unclean_filename);      std::string filename = LLDir::getScrubbedFileName(unclean_filename); +    LLMuteList* mute_list = getInstance(); +    mute_list->mLoadState = ML_REQUESTED; +    mute_list->mRequestStartTime = LLTimer::getElapsedSeconds(); + +    // Todo: Based of logs and testing, there is no callback +    // from server if file doesn't exist server side. +    // Once server side gets fixed make sure it gets handled right.      std::string *local_filename_and_path = new std::string(gDirUtilp->getExpandedFilename( LL_PATH_CACHE, filename ));      gXferManager->requestFile(*local_filename_and_path,                                filename, @@ -809,12 +843,16 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_          LLMuteList::getInstance()->loadFromFile(*local_filename_and_path);          LLFile::remove(*local_filename_and_path);      } +    else +    { +        LLMuteList::getInstance()->mLoadState = ML_FAILED; +    }      delete local_filename_and_path;  }  void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username)  { -    if (mIsLoaded) +    if (isLoaded())      {          LLMute mute(id, username, LLMute::AGENT);          mute_set_t::iterator mute_it = mMutes.find(mute); @@ -866,7 +904,7 @@ void LLMuteList::removeObserver(LLMuteListObserver* observer)  void LLMuteList::setLoaded()  { -    mIsLoaded = true; +    mLoadState = ML_LOADED;      notifyObservers();  } diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 13d579c61f..b65fd61fcc 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -74,6 +74,14 @@ class LLMuteList : public LLSingleton<LLMuteList>      LLSINGLETON(LLMuteList);      ~LLMuteList();      /*virtual*/ void cleanupSingleton() override; + +    enum EMuteListState +    { +        ML_INITIAL, +        ML_REQUESTED, +        ML_LOADED, +        ML_FAILED, +    };  public:      // reasons for auto-unmuting a resident      enum EAutoReason @@ -107,7 +115,8 @@ public:      static bool isLinden(const std::string& name); -    bool isLoaded() const { return mIsLoaded; } +    bool isLoaded() const { return mLoadState == ML_LOADED; } +    bool getLoadFailed() const;      std::vector<LLMute> getMutes() const; @@ -167,7 +176,8 @@ private:      typedef std::set<LLMuteListObserver*> observer_set_t;      observer_set_t mObservers; -    bool mIsLoaded; +    EMuteListState mLoadState; +    F64 mRequestStartTime;      friend class LLDispatchEmptyMuteList;  }; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index df53c66ec1..36ffcae8df 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -34,10 +34,12 @@  #include "llaccordionctrl.h"  #include "llaccordionctrltab.h"  #include "llagentwearables.h" +#include "llaisapi.h"  #include "llappearancemgr.h"  #include "llfloaterreg.h"  #include "llfloatersidepanelcontainer.h"  #include "llinspecttexture.h" +#include "llinventorymodelbackgroundfetch.h"  #include "llinventoryfunctions.h"  #include "llinventorymodel.h"  #include "llmenubutton.h" @@ -205,12 +207,22 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)      list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3)); -    // Fetch the new outfit contents. -    cat->fetch(); - -    // Refresh the list of outfit items after fetch(). -    // Further list updates will be triggered by the category observer. -    list->updateList(cat_id); +    if (AISAPI::isAvailable() && LLInventoryModelBackgroundFetch::instance().folderFetchActive()) +    { +        // for reliability just fetch it whole, linked items included +        LLInventoryModelBackgroundFetch::instance().fetchFolderAndLinks(cat_id, [cat_id, list] +        { +            if (list) list->updateList(cat_id); +        }); +    } +    else +    { +        // Fetch the new outfit contents. +        cat->fetch(); +        // Refresh the list of outfit items after fetch(). +        // Further list updates will be triggered by the category observer. +        list->updateList(cat_id); +    }      // If filter is currently applied we store the initial tab state.      if (!getFilterSubString().empty()) diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp index 3a6a6a5ec3..f0555408dd 100644 --- a/indra/newview/llpanelemojicomplete.cpp +++ b/indra/newview/llpanelemojicomplete.cpp @@ -463,6 +463,7 @@ void LLPanelEmojiComplete::updateConstraints()      {          mEmojiHeight = mRenderRect.getHeight();          mRenderRect.stretch((mRenderRect.getWidth() - static_cast<S32>(mVisibleEmojis) * mEmojiWidth) / -2, 0); +        mRenderRect.translate(-mRenderRect.mLeft, 0); // Left align emojis to fix hitboxes      }      updateScrollPos(); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 25dd37590d..9076576f00 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2209,7 +2209,7 @@ void LLPanelFace::refreshMedia()      // check if all faces have media(or, all dont have media) -    LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media); +    bool identical_has_media_info = selected_objects->getSelectedTEValue(&func, bool_has_media);      const LLMediaEntry default_media_data; @@ -2231,7 +2231,8 @@ void LLPanelFace::refreshMedia()      } func_media_data(default_media_data);      LLMediaEntry media_data_get; -    LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get)); +    bool multiple_media = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get)); +    bool multiple_valid_media = false;      std::string multi_media_info_str = LLTrans::getString("Multiple Media");      std::string media_title = ""; @@ -2240,12 +2241,12 @@ void LLPanelFace::refreshMedia()      mAddMedia->setEnabled(editable);      // IF all the faces have media (or all dont have media) -    if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo) +    if (identical_has_media_info)      {          // TODO: get media title and set it.          mTitleMediaText->clear();          // if identical is set, all faces are same (whether all empty or has the same media) -        if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia)) +        if (!multiple_media)          {              // Media data is valid              if (media_data_get != default_media_data) @@ -2266,9 +2267,9 @@ void LLPanelFace::refreshMedia()      else // not all face has media but at least one does.      {          // seleted faces have not identical value -        LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data); +        multiple_valid_media = selected_objects->isMultipleTEValue(&func_media_data, default_media_data); -        if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) +        if (multiple_valid_media)          {              media_title = multi_media_info_str;          } @@ -2305,7 +2306,7 @@ void LLPanelFace::refreshMedia()      // load values for media settings      updateMediaSettings(); -    LLFloaterMediaSettings::initValues(mMediaSettings, editable); +    LLFloaterMediaSettings::initValues(mMediaSettings, editable, identical_has_media_info, multiple_media, multiple_valid_media);  }  void LLPanelFace::unloadMedia() @@ -3378,6 +3379,7 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data)  // TODO: test if there is media on the item and only allow editing if present  void LLPanelFace::onClickBtnEditMedia()  { +    LLFloaterMediaSettings::getInstance(); // make sure floater we are about to open exists before refreshMedia      refreshMedia();      LLFloaterReg::showInstance("media_settings");  } @@ -3396,6 +3398,7 @@ void LLPanelFace::onClickBtnAddMedia()      // check if multiple faces are selected      if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())      { +        LLFloaterMediaSettings::getInstance(); // make sure floater we are about to open exists before refreshMedia          refreshMedia();          LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);      } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index ed80c8b732..59aa375457 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -184,7 +184,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,      mCallback(callback),      mCallbackData(cb_data),      mListener(new LLPanelLoginListener(this)), -    mFirstLoginThisInstall(gSavedSettings.getBOOL("FirstLoginThisInstall")),      mUsernameLength(0),      mPasswordLength(0),      mLocationLength(0), @@ -203,14 +202,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,          login_holder->addChild(this);      } -    if (mFirstLoginThisInstall) -    { -        buildFromFile( "panel_login_first.xml"); -    } -    else -    { -        buildFromFile( "panel_login.xml"); -    } +    buildFromFile("panel_login.xml");      reshape(rect.getWidth(), rect.getHeight()); @@ -224,38 +216,36 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,      sendChildToBack(getChildView("sign_up_text"));      std::string current_grid = LLGridManager::getInstance()->getGrid(); -    if (!mFirstLoginThisInstall) -    { -        LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo"); -        updateLocationSelectorsVisibility(); // separate so that it can be called from preferences -        favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false)); -        favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this)); -        LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo"); -        server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this)); +    LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo"); +    updateLocationSelectorsVisibility(); // separate so that it can be called from preferences +    favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false)); +    favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this)); + +    LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo"); +    server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this)); -        // Load all of the grids, sorted, and then add a bar and the current grid at the top -        server_choice_combo->removeall(); +    // Load all of the grids, sorted, and then add a bar and the current grid at the top +    server_choice_combo->removeall(); -        std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); -        for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); -            grid_choice != known_grids.end(); -            grid_choice++) +    std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); +    for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); +        grid_choice != known_grids.end(); +        grid_choice++) +    { +        if (!grid_choice->first.empty() && current_grid != grid_choice->first)          { -            if (!grid_choice->first.empty() && current_grid != grid_choice->first) -            { -                LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL; -                server_choice_combo->add(grid_choice->second, grid_choice->first); -            } +            LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL; +            server_choice_combo->add(grid_choice->second, grid_choice->first);          } -        server_choice_combo->sortByName(); - -        LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL; -        server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), -            current_grid, -            ADD_TOP); -        server_choice_combo->selectFirstItem();      } +    server_choice_combo->sortByName(); + +    LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL; +    server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), +        current_grid, +        ADD_TOP); +    server_choice_combo->selectFirstItem();      LLSLURL start_slurl(LLStartUp::getStartSLURL());      // The StartSLURL might have been set either by an explicit command-line @@ -331,15 +321,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,  void LLPanelLogin::addFavoritesToStartLocation()  { -    if (mFirstLoginThisInstall) -    { -        // first login panel has no favorites, just update name length and buttons -        std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple(); -        mUsernameLength = static_cast<unsigned int>(user_defined_name.length()); -        updateLoginButtons(); -        return; -    } -      // Clear the combo.      LLComboBox* combo = getChild<LLComboBox>("start_location_combo");      if (!combo) return; @@ -559,16 +540,9 @@ void LLPanelLogin::resetFields()          // function is used to reset list in case of changes by external sources          return;      } -    if (sInstance->mFirstLoginThisInstall) -    { -        // no list to populate -        LL_WARNS() << "Shouldn't happen, user should have no ability to modify list on first install" << LL_ENDL; -    } -    else -    { -        LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); -        sInstance->populateUserList(cred); -    } + +    LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); +    sInstance->populateUserList(cred);  }  // static @@ -586,7 +560,6 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential)      if(identifier.has("type") && (std::string)identifier["type"] == "agent")      { -        // not nessesary for panel_login.xml, needed for panel_login_first.xml          std::string firstname = identifier["first_name"].asString();          std::string lastname = identifier["last_name"].asString();          std::string login_id = firstname; @@ -1081,8 +1054,7 @@ void LLPanelLogin::onRememberUserCheck(void*)          LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo"));          bool remember = remember_name->getValue().asBoolean(); -        if (!sInstance->mFirstLoginThisInstall -            && user_combo->getCurrentIndex() != -1 +        if (user_combo->getCurrentIndex() != -1              && !remember)          {              remember = true; @@ -1197,17 +1169,14 @@ void LLPanelLogin::updateLoginButtons()      login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0); -    if (!mFirstLoginThisInstall) +    LLComboBox* user_combo = getChild<LLComboBox>("username_combo"); +    LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name"); +    if (user_combo->getCurrentIndex() != -1)      { -        LLComboBox* user_combo = getChild<LLComboBox>("username_combo"); -        LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name"); -        if (user_combo->getCurrentIndex() != -1) -        { -            remember_name->setValue(true); -            LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password"); -            remember_pass->setEnabled(true); -        } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user -    } +        remember_name->setValue(true); +        LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password"); +        remember_pass->setEnabled(true); +    } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user  }  void LLPanelLogin::populateUserList(LLPointer<LLCredential> credential) diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index a1bf25fb05..1259bf26d6 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -119,7 +119,6 @@ private:      static LLPanelLogin* sInstance;      static bool     sCapslockDidNotification; -    bool            mFirstLoginThisInstall;      static bool sCredentialSet; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 25672db318..33599357a3 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -843,6 +843,10 @@ void LLPanelPeople::updateNearbyList()      LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));      mNearbyList->setDirty(); +#ifdef LL_DISCORD +    if (gSavedSettings.getBOOL("EnableDiscord")) +        LLAppViewer::updateDiscordPartyMaxSize((S32)mNearbyList->getIDs().size()); +#endif      DISTANCE_COMPARATOR.updateAvatarsPositions(positions, mNearbyList->getIDs());      LLActiveSpeakerMgr::instance().update(true); diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index f8a73ddb46..939b1f12a9 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -154,11 +154,15 @@ void PeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)  bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata)  { +    std::string item = userdata.asString();      if(gAgent.getID() == mUUIDs.front())      { +        if (item == std::string("can_zoom_in")) +        { +            return true; +        }          return false;      } -    std::string item = userdata.asString();      // Note: can_block and can_delete is used only for one person selected menu      // so we don't need to go over all uuids. diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 4956c188fb..b49c0119ed 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -1026,6 +1026,10 @@ void LLLocalSpeakerMgr::updateSpeakerList()      uuid_vec_t avatar_ids;      std::vector<LLVector3d> positions;      LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS); +#ifdef LL_DISCORD +    if (gSavedSettings.getBOOL("EnableDiscord")) +        LLAppViewer::updateDiscordPartyCurrentSize((S32)avatar_ids.size()); +#endif      for(U32 i=0; i<avatar_ids.size(); i++)      {          setSpeaker(avatar_ids[i]); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6bf0a50d1c..2409b71f00 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -724,6 +724,10 @@ bool idle_startup()              LL_WARNS("AppInit") << "Unreliable timers detected (may be bad PCI chipset)!!" << LL_ENDL;          } +#ifdef LL_DISCORD +        LLAppViewer::initDiscordSocial(); +#endif +          //          // Log on to system          // diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 8aa2058ae1..bb93e2e79e 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -114,6 +114,8 @@ LLStatusBar::LLStatusBar(const LLRect& rect)      mBtnVolume(NULL),      mBoxBalance(NULL),      mBalance(0), +    mBalanceClicked(false), +    mObscureBalance(false),      mHealth(100),      mSquareMetersCredit(0),      mSquareMetersCommitted(0), @@ -125,20 +127,11 @@ LLStatusBar::LLStatusBar(const LLRect& rect)      // status bar can possible overlay menus?      setMouseOpaque(false); -    mBalanceTimer = new LLFrameTimer(); -    mHealthTimer = new LLFrameTimer(); -      buildFromFile("panel_status_bar.xml");  }  LLStatusBar::~LLStatusBar()  { -    delete mBalanceTimer; -    mBalanceTimer = NULL; - -    delete mHealthTimer; -    mHealthTimer = NULL; -      // LLView destructor cleans up children  } @@ -171,7 +164,8 @@ bool LLStatusBar::postBuild()      getChild<LLUICtrl>("goShop")->setCommitCallback(boost::bind(&LLWeb::loadURL, gSavedSettings.getString("MarketplaceURL"), LLStringUtil::null, LLStringUtil::null));      mBoxBalance = getChild<LLTextBox>("balance"); -    mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this ); +    mBoxBalance->setClickedCallback(&LLStatusBar::onClickRefreshBalance, this); +    mBoxBalance->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onClickToggleBalance(); });      mIconPresetsCamera = getChild<LLIconCtrl>( "presets_icon_camera" );      mIconPresetsCamera->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresetsCamera, this)); @@ -191,12 +185,14 @@ bool LLStatusBar::postBuild()      gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2));      gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&LLStatusBar::onVoiceChanged, this, _2)); +    gSavedSettings.getControl("ObscureBalanceInStatusBar")->getSignal()->connect(boost::bind(&LLStatusBar::onObscureBalanceChanged, this, _2));      if (!gSavedSettings.getBOOL("EnableVoiceChat") && LLAppViewer::instance()->isSecondInstance())      {          // Indicate that second instance started without sound          mBtnVolume->setImageUnselected(LLUI::getUIImage("VoiceMute_Off"));      } +    mObscureBalance = gSavedSettings.getBOOL("ObscureBalanceInStatusBar");      // Adding Net Stat Graph      S32 x = getRect().getWidth() - 2; @@ -319,6 +315,12 @@ void LLStatusBar::refresh()          mTextTime->setToolTip (dtStr);      } +    if (mBalanceClicked && mBalanceClickTimer.getElapsedTimeF32() > 1.f) +    { +        mBalanceClicked = false; +        sendMoneyBalanceRequest(); +    } +      LLRect r;      const S32 MENU_RIGHT = gMenuBarView->getRightmostMenuEdge(); @@ -384,9 +386,17 @@ void LLStatusBar::setBalance(S32 balance)      std::string money_str = LLResMgr::getInstance()->getMonetaryString( balance );      LLStringUtil::format_map_t string_args; -    string_args["[AMT]"] = llformat("%s", money_str.c_str()); +    if (mObscureBalance) +    { +        string_args["[AMT]"] = "****"; +    } +    else +    { +        string_args["[AMT]"] = llformat("%s", money_str.c_str()); +    }      std::string label_str = getString("buycurrencylabel", string_args);      mBoxBalance->setValue(label_str); +    mBoxBalance->setToolTipArg(LLStringExplicit("[AMT]"), llformat("%s", money_str.c_str()));      updateBalancePanelPosition(); @@ -406,8 +416,6 @@ void LLStatusBar::setBalance(S32 balance)      if( balance != mBalance )      { -        mBalanceTimer->reset(); -        mBalanceTimer->setTimerExpirySec( ICON_TIMER_EXPIRY );          mBalance = balance;      }  } @@ -459,9 +467,6 @@ void LLStatusBar::setHealth(S32 health)                  }              }          } - -        mHealthTimer->reset(); -        mHealthTimer->setTimerExpirySec( ICON_TIMER_EXPIRY );      }      mHealth = health; @@ -621,13 +626,27 @@ static void onClickVolume(void* data)  }  //static -void LLStatusBar::onClickBalance(void* ) +void LLStatusBar::onClickRefreshBalance(void* data)  { -    // Force a balance request message: -    LLStatusBar::sendMoneyBalanceRequest(); +    LLStatusBar* status_bar = (LLStatusBar*)data; + +    if (!status_bar->mBalanceClicked) +    { +        // Schedule a balance request message: +        status_bar->mBalanceClicked = true; +        status_bar->mBalanceClickTimer.reset(); +    }      // The refresh of the display (call to setBalance()) will be done by process_money_balance_reply()  } +void LLStatusBar::onClickToggleBalance() +{ +    mObscureBalance = !mObscureBalance; +    gSavedSettings.setBOOL("ObscureBalanceInStatusBar", mObscureBalance); +    setBalance(mBalance); +    mBalanceClicked = false; // supress click +} +  //static  void LLStatusBar::onClickMediaToggle(void* data)  { @@ -657,6 +676,12 @@ void LLStatusBar::onVoiceChanged(const LLSD& newvalue)      refresh();  } +void LLStatusBar::onObscureBalanceChanged(const LLSD& newvalue) +{ +    mObscureBalance = newvalue.asBoolean(); +    setBalance(mBalance); +} +  void LLStatusBar::onUpdateFilterTerm()  {      LLWString searchValue = utf8str_to_wstring( mFilterEdit->getValue() ); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 45cbda0ef1..a8fc621ff8 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -72,7 +72,8 @@ public:      void        debitBalance(S32 debit);      void        creditBalance(S32 credit); -    // Request the latest currency balance from the server +    // Request the latest currency balance from the server. +    // Reply at process_money_balance_reply()      static void sendMoneyBalanceRequest();      void        setHealth(S32 percent); @@ -102,6 +103,7 @@ private:      void onClickBuyCurrency();      void onVolumeChanged(const LLSD& newvalue);      void onVoiceChanged(const LLSD& newvalue); +    void onObscureBalanceChanged(const LLSD& newvalue);      void onMouseEnterPresetsCamera();      void onMouseEnterPresets(); @@ -109,7 +111,8 @@ private:      void onMouseEnterNearbyMedia();      static void onClickMediaToggle(void* data); -    static void onClickBalance(void* data); +    static void onClickRefreshBalance(void* data); +    void onClickToggleBalance();      LLSearchEditor *mFilterEdit;      LLPanel *mSearchPanel; @@ -135,11 +138,12 @@ private:      LLFrameTimer    mClockUpdateTimer;      S32             mBalance; +    bool            mBalanceClicked; +    bool            mObscureBalance; +    LLTimer         mBalanceClickTimer;      S32             mHealth;      S32             mSquareMetersCredit;      S32             mSquareMetersCommitted; -    LLFrameTimer*   mBalanceTimer; -    LLFrameTimer*   mHealthTimer;      LLPanelPresetsCameraPulldown* mPanelPresetsCameraPulldown;      LLPanelPresetsPulldown* mPanelPresetsPulldown;      LLPanelVolumePulldown* mPanelVolumePulldown; diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp index b68ffbe1a2..4a1c433f8e 100644 --- a/indra/newview/llviewermedia_streamingaudio.cpp +++ b/indra/newview/llviewermedia_streamingaudio.cpp @@ -60,13 +60,26 @@ void LLStreamingAudio_MediaPlugins::start(const std::string& url)      if(!mMediaPlugin)          return; -    if (!url.empty()) { +    if (!url.empty()) +    {          LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; -        mURL = url; -        mMediaPlugin->loadURI ( url ); + +        mURL = url; // keep original url here for comparison purposes +        std::string snt_url = url; +        LLStringUtil::trim(snt_url); +        size_t pos = snt_url.find(' '); +        if (pos != std::string::npos) +        { +            // fmod permited having names after the url and people were using it. +            // People label their streams this way, ignore the 'label'. +            snt_url = snt_url.substr(0, pos); +        } +        mMediaPlugin->loadURI(snt_url);          mMediaPlugin->start();          LL_INFOS() << "Playing stream..." << LL_ENDL; -    } else { +    } +    else +    {          LL_INFOS() << "setting stream to NULL"<< LL_ENDL;          mURL.clear();          mMediaPlugin->stop(); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 84195997c3..990296c11e 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -69,6 +69,7 @@  #include "llviewerassetupload.h"  // linden libraries +#include "llfilesystem.h"  #include "llnotificationsutil.h"  #include "llsdserialize.h"  #include "llsdutil.h" @@ -544,16 +545,9 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)          if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec))          {              bool resource_upload = false; -            if (asset_type == LLAssetType::AT_TEXTURE && allow_2k) +            if (asset_type == LLAssetType::AT_TEXTURE)              { -                LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec); -                if (gDirUtilp->fileExists(filename) && image_frmted && image_frmted->load(filename)) -                { -                    S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getWidth(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); -                    S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getHeight(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); -                    expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(biased_width, biased_height); -                    resource_upload = true; -                } +                resource_upload = true;              }              else if (LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))              { @@ -562,23 +556,115 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)              if (resource_upload)              { -                LLNewFileResourceUploadInfo* info_p = new LLNewFileResourceUploadInfo( -                    filename, -                    asset_name, -                    asset_name, 0, -                    LLFolderType::FT_NONE, LLInventoryType::IT_NONE, -                    LLFloaterPerms::getNextOwnerPerms("Uploads"), -                    LLFloaterPerms::getGroupPerms("Uploads"), -                    LLFloaterPerms::getEveryonePerms("Uploads"), -                    expected_upload_cost); - -                if (!allow_2k) +                if (asset_type == LLAssetType::AT_TEXTURE)                  { -                    info_p->setMaxImageSize(1024); -                } -                LLResourceUploadInfo::ptr_t uploadInfo(info_p); +                    std::string exten = gDirUtilp->getExtension(filename); +                    U32         codec = LLImageBase::getCodecFromExtension(exten); + +                    // Load the image +                    LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec); +                    if (image.isNull()) +                    { +                        LL_WARNS() << "Failed to create image container for " << filename << LL_ENDL; +                        continue; +                    } +                    if (!image->load(filename)) +                    { +                        LL_WARNS() << "Failed to load image: " << filename << LL_ENDL; +                        continue; +                    } +                    // Decompress or expand it in a raw image structure +                    LLPointer<LLImageRaw> raw_image = new LLImageRaw; +                    if (!image->decode(raw_image, 0.0f)) +                    { +                        LL_WARNS() << "Failed to decode image: " << filename << LL_ENDL; +                        continue; +                    } +                    // Check the image constraints +                    if ((image->getComponents() != 3) && (image->getComponents() != 4)) +                    { +                        LL_WARNS() << "Attempted to upload a texture that has " << image->getComponents() +                                   << " components, but only 3 (RGB) or 4 (RGBA) are allowed." << LL_ENDL; +                        continue; +                    } +                    // Downscale images to fit the max_texture_dimensions_*, or 1024 if allow_2k is false +                    S32 max_width  = allow_2k ? gSavedSettings.getS32("max_texture_dimension_X") : 1024; +                    S32 max_height = allow_2k ? gSavedSettings.getS32("max_texture_dimension_Y") : 1024; + +                    S32 orig_width  = raw_image->getWidth(); +                    S32 orig_height = raw_image->getHeight(); + +                    if (orig_width > max_width || orig_height > max_height) +                    { +                        // Calculate scale factors +                        F32 width_scale  = (F32)max_width / (F32)orig_width; +                        F32 height_scale = (F32)max_height / (F32)orig_height; +                        F32 scale        = llmin(width_scale, height_scale); + +                        // Calculate new dimensions, preserving aspect ratio +                        S32 new_width  = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_width * scale), 4, max_width)); +                        S32 new_height = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_height * scale), 4, max_height)); + +                        if (!raw_image->scale(new_width, new_height)) +                        { +                            LL_WARNS() << "Failed to scale image from " << orig_width << "x" << orig_height << " to " << new_width << "x" +                                       << new_height << LL_ENDL; +                            continue; +                        } + +                        // Inform the resident about the resized image +                        LLSD subs; +                        subs["[ORIGINAL_WIDTH]"]  = orig_width; +                        subs["[ORIGINAL_HEIGHT]"] = orig_height; +                        subs["[NEW_WIDTH]"]       = new_width; +                        subs["[NEW_HEIGHT]"]      = new_height; +                        subs["[MAX_WIDTH]"]       = max_width; +                        subs["[MAX_HEIGHT]"]      = max_height; +                        LLNotificationsUtil::add("ImageUploadResized", subs); +                    } + +                    raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + +                    LLTransactionID tid; +                    tid.generate(); +                    LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); -                upload_new_resource(uploadInfo); +                    LLPointer<LLImageJ2C> formatted = new LLImageJ2C; + +                    if (formatted->encode(raw_image, 0.0f)) +                    { +                        LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE); +                        fmt_file.write(formatted->getData(), formatted->getDataSize()); + +                        LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo( +                            tid, LLAssetType::AT_TEXTURE, +                            asset_name, +                            asset_name, 0, +                            LLFolderType::FT_NONE, LLInventoryType::IT_NONE, +                            LLFloaterPerms::getNextOwnerPerms("Uploads"), +                            LLFloaterPerms::getGroupPerms("Uploads"), +                            LLFloaterPerms::getEveryonePerms("Uploads"), +                            LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight()) +                        )); + +                        upload_new_resource(assetUploadInfo); +                    } +                } +                else +                { +                    LLNewFileResourceUploadInfo* info_p = new LLNewFileResourceUploadInfo( +                        filename, +                        asset_name, +                        asset_name, 0, +                        LLFolderType::FT_NONE, LLInventoryType::IT_NONE, +                        LLFloaterPerms::getNextOwnerPerms("Uploads"), +                        LLFloaterPerms::getGroupPerms("Uploads"), +                        LLFloaterPerms::getEveryonePerms("Uploads"), +                        expected_upload_cost); +                    LLResourceUploadInfo::ptr_t uploadInfo(info_p); + +                    upload_new_resource(uploadInfo); +                }              }          } @@ -647,8 +733,31 @@ bool get_bulk_upload_expected_cost(                  LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec);                  if (gDirUtilp->fileExists(filename) && image_frmted && image_frmted->load(filename))                  { -                    S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getWidth(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); -                    S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getHeight(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +                    S32 biased_width, biased_height; + +                    S32 max_width  = allow_2k ? gSavedSettings.getS32("max_texture_dimension_X") : 1024; +                    S32 max_height = allow_2k ? gSavedSettings.getS32("max_texture_dimension_Y") : 1024; + +                    S32 orig_width  = image_frmted->getWidth(); +                    S32 orig_height = image_frmted->getHeight(); + +                    if (orig_width > max_width || orig_height > max_height) +                    { +                        // Calculate scale factors +                        F32 width_scale  = (F32)max_width / (F32)orig_width; +                        F32 height_scale = (F32)max_height / (F32)orig_height; +                        F32 scale        = llmin(width_scale, height_scale); + +                        // Calculate new dimensions, preserving aspect ratio +                        biased_width = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_width * scale), 4, max_width)); +                        biased_height = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_height * scale), 4, max_height)); +                    } +                    else +                    { +                        biased_width = LLImageRaw::biasedDimToPowerOfTwo(orig_width, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +                        biased_height = LLImageRaw::biasedDimToPowerOfTwo(orig_height, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); +                    } +                      total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(biased_width, biased_height);                      S32 area = biased_width * biased_height;                      if (area >= LLAgentBenefits::MIN_2K_TEXTURE_AREA) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 1501ba41c2..44831aea03 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3052,6 +3052,11 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)          }      } +#ifdef LL_DISCORD +    if (gSavedSettings.getBOOL("EnableDiscord")) +        LLAppViewer::updateDiscordActivity(); +#endif +      if ( LLTracker::isTracking(NULL) )      {          // Check distance to beacon, if < 5m, remove beacon @@ -3189,6 +3194,7 @@ void send_agent_update(bool force_send, bool send_reliable)      static F64          last_send_time = 0.0;      static U32          last_control_flags = 0; +    static bool         control_flags_follow_up = false;      static U8           last_render_state = 0;      static U8           last_flags = AU_FLAGS_NONE;      static LLQuaternion last_body_rot, @@ -3266,6 +3272,20 @@ void send_agent_update(bool force_send, bool send_reliable)                  break;              } +            // example: +            // user taps crouch (control_flags 4128), viewer sends 4128 then immediately 0 +            // server starts crouching motion but does not stop it, only once viewer sends 0 +            // second time will server stop the motion. follow_up exists to make sure all +            // states like 'crouch' motion are properly cleared server side. +            // +            // P.S. Server probably shouldn't require a reminder to stop a motion, +            // but at the moment it does. +            if (control_flags_follow_up) +            { +                send_update = true; +                break; +            } +              // check translation              constexpr F32 TRANSLATE_THRESHOLD = 0.01f;              if ((last_camera_pos_agent - camera_pos_agent).magVec() > TRANSLATE_THRESHOLD) @@ -3399,6 +3419,7 @@ void send_agent_update(bool force_send, bool send_reliable)      // remember last update data      last_send_time = now; +    control_flags_follow_up = last_control_flags != control_flags;      last_control_flags = control_flags;      last_render_state = render_state;      last_flags = flags; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index dcba891f9f..dd59979a6c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -678,6 +678,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,      mVisuallyMuteSetting(AV_RENDER_NORMALLY),      mMutedAVColor(LLColor4::white /* used for "uninitialize" */),      mFirstFullyVisible(true), +    mWaitingForMeshes(false),      mFirstDecloudTime(-1.f),      mFullyLoaded(false),      mPreviousFullyLoaded(false), @@ -920,12 +921,12 @@ bool LLVOAvatar::isFullyTextured() const  bool LLVOAvatar::hasGray() const  { -    return !getIsCloud() && !isFullyTextured(); +    return !getHasMissingParts() && !isFullyTextured();  }  S32 LLVOAvatar::getRezzedStatus() const  { -    if (getIsCloud()) return 0; +    if (getHasMissingParts()) return 0;      bool textured = isFullyTextured();      bool all_baked_loaded = allBakedTexturesCompletelyDownloaded();      if (textured && all_baked_loaded && getAttachmentCount() == mSimAttachments.size()) return 4; @@ -972,30 +973,45 @@ bool LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)  }  // static -void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars) +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars)  {      counts.clear();      counts.resize(5);      avg_cloud_time = 0;      cloud_avatars = 0; +    pending_meshes = 0; +    control_avatars = 0;      S32 count_avg = 0;      for (LLCharacter* character : LLCharacter::sInstances)      { -        if (LLVOAvatar* inst = (LLVOAvatar*)character) +        LLVOAvatar* inst = (LLVOAvatar*)character; +        if (inst && !inst->isUIAvatar() && !inst->isSelf())          { -            S32 rez_status = inst->getRezzedStatus(); -            counts[rez_status]++; -            F32 time = inst->getFirstDecloudTime(); -            if (time >= 0) +            if (inst->isControlAvatar())              { -                avg_cloud_time+=time; -                count_avg++; +                control_avatars++;              } -            if (!inst->isFullyLoaded() || time < 0) +            else              { -                // still renders as cloud -                cloud_avatars++; +                S32 rez_status = inst->getRezzedStatus(); +                counts[rez_status]++; +                F32 time = inst->getFirstDecloudTime(); +                if (time >= 0) +                { +                    avg_cloud_time += time; +                    count_avg++; +                } +                if (!inst->isFullyLoaded() || time < 0) +                { +                    // still renders as cloud +                    cloud_avatars++; +                    if (rez_status >= 4 +                        && inst->mWaitingForMeshes) +                    { +                        pending_meshes++; +                    } +                }              }          }      } @@ -1012,7 +1028,7 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status)      switch (rez_status)      {      case 0: -        return "cloud"; +        return "missing parts";      case 1:          return "gray";      case 2: @@ -3474,7 +3490,7 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name)          is_muted = isInMuteList();      }      bool is_friend = isBuddy(); -    bool is_cloud = getIsCloud(); +    bool is_cloud = getHasMissingParts();      if (is_appearance != mNameAppearance)      { @@ -8201,7 +8217,7 @@ bool LLVOAvatar::isVisible() const  }  // Determine if we have enough avatar data to render -bool LLVOAvatar::getIsCloud() const +bool LLVOAvatar::getHasMissingParts() const  {      if (mIsDummy)      { @@ -8408,8 +8424,12 @@ bool LLVOAvatar::updateIsFullyLoaded()                     || (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC)                     || !mPendingAttachment.empty()                     || (rez_status < 3 && !isFullyBaked()) -                   || hasPendingAttachedMeshes()                    ); +        if (!loading) +        { +            mWaitingForMeshes = hasPendingAttachedMeshes(); +            loading = mWaitingForMeshes; +        }          // compare amount of attachments to one reported by simulator          if (!isSelf() && mLastCloudAttachmentCount < mSimAttachments.size() && mSimAttachments.size() > 0) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 9eb8d3f880..178665f4c5 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -400,7 +400,7 @@ public:      bool            isTooComplex() const;      bool            visualParamWeightsAreDefault(); -    virtual bool    getIsCloud() const; +    virtual bool    getHasMissingParts() const;      bool            isFullyTextured() const;      bool            hasGray() const;      S32             getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded. @@ -427,6 +427,7 @@ protected:  private:      bool            mFirstFullyVisible; +    bool            mWaitingForMeshes;      F32             mFirstDecloudTime;      LLFrameTimer    mFirstAppearanceMessageTimer; @@ -723,7 +724,7 @@ public:      bool            isFullyBaked();      static bool     areAllNearbyInstancesBaked(S32& grey_avatars); -    static void     getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars); +    static void     getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars);      static std::string rezStatusToString(S32 status);      //-------------------------------------------------------------------- diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index ebba9ba291..653c7e82eb 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1927,7 +1927,7 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()      LL_INFOS() << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << LL_ENDL;  } -bool LLVOAvatarSelf::getIsCloud() const +bool LLVOAvatarSelf::getHasMissingParts() const  {      // Let people know why they're clouded without spamming them into oblivion.      bool do_warn = false; @@ -2237,14 +2237,18 @@ void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url)      std::vector<S32> rez_counts;      F32 avg_time;      S32 total_cloud_avatars; -    LLVOAvatar::getNearbyRezzedStats(rez_counts, avg_time, total_cloud_avatars); +    S32 waiting_for_meshes; +    S32 control_avatars; +    LLVOAvatar::getNearbyRezzedStats(rez_counts, avg_time, total_cloud_avatars, waiting_for_meshes, control_avatars);      for (S32 rez_stat = 0; rez_stat < rez_counts.size(); ++rez_stat)      {          std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);          msg["nearby"][rez_status_name] = rez_counts[rez_stat];      } +    msg["nearby"]["waiting_for_meshes"] = waiting_for_meshes;      msg["nearby"]["avg_decloud_time"] = avg_time;      msg["nearby"]["cloud_total"] = total_cloud_avatars; +    msg["nearby"]["animeshes"] = control_avatars;      //  std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");      std::vector<std::string> by_fields; @@ -2826,6 +2830,12 @@ void LLVOAvatarSelf::setHoverOffset(const LLVector3& hover_offset, bool send_upd  //------------------------------------------------------------------------  bool LLVOAvatarSelf::needsRenderBeam()  { +    static LLCachedControl<bool> enable_selection_hints(gSavedSettings, "EnableSelectionHints", true); +    if (!enable_selection_hints) +    { +        return false; +    } +      LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();      bool is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing()); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index f7cd974ab0..45985b2a80 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -129,7 +129,7 @@ public:      // Loading state      //--------------------------------------------------------------------  public: -    /*virtual*/ bool    getIsCloud() const; +    /*virtual*/ bool    getHasMissingParts() const;      //--------------------------------------------------------------------      // Region state diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 9835a69e4e..627d759df4 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -336,35 +336,37 @@ void LLWebRTCVoiceClient::updateSettings()      LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;      setVoiceEnabled(LLVoiceClient::getInstance()->voiceEnabled()); -    static LLCachedControl<S32> sVoiceEarLocation(gSavedSettings, "VoiceEarLocation"); -    setEarLocation(sVoiceEarLocation); - -    static LLCachedControl<std::string> sInputDevice(gSavedSettings, "VoiceInputAudioDevice"); -    setCaptureDevice(sInputDevice); +    if (mVoiceEnabled) +    { +        static LLCachedControl<S32> sVoiceEarLocation(gSavedSettings, "VoiceEarLocation"); +        setEarLocation(sVoiceEarLocation); -    static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice"); -    setRenderDevice(sOutputDevice); +        static LLCachedControl<std::string> sInputDevice(gSavedSettings, "VoiceInputAudioDevice"); +        setCaptureDevice(sInputDevice); -    LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL; +        static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice"); +        setRenderDevice(sOutputDevice); -    static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic"); -    setMicGain(sMicLevel); +        LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL; -    llwebrtc::LLWebRTCDeviceInterface::AudioConfig config; +        static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic"); +        setMicGain(sMicLevel); -    static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true); -    config.mEchoCancellation = sEchoCancellation; +        llwebrtc::LLWebRTCDeviceInterface::AudioConfig config; -    static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true); -    config.mAGC = sAGC; +        static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true); +        config.mEchoCancellation = sEchoCancellation; -    static LLCachedControl<U32> sNoiseSuppressionLevel(gSavedSettings, -                                                       "VoiceNoiseSuppressionLevel", -                                                       llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH); -    config.mNoiseSuppressionLevel = (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel) (U32)sNoiseSuppressionLevel; +        static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true); +        config.mAGC = sAGC; -    mWebRTCDeviceInterface->setAudioConfig(config); +        static LLCachedControl<U32> sNoiseSuppressionLevel(gSavedSettings, +            "VoiceNoiseSuppressionLevel", +            llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH); +        config.mNoiseSuppressionLevel = (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel)(U32)sNoiseSuppressionLevel; +        mWebRTCDeviceInterface->setAudioConfig(config); +    }  }  // Observers diff --git a/indra/newview/res/ll_icon_small.ico b/indra/newview/res/ll_icon_small.icoBinary files differ new file mode 100644 index 0000000000..a3f6877935 --- /dev/null +++ b/indra/newview/res/ll_icon_small.ico diff --git a/indra/newview/res/resource.h b/indra/newview/res/resource.h index e904f4a1a8..1d3289d784 100644 --- a/indra/newview/res/resource.h +++ b/indra/newview/res/resource.h @@ -30,6 +30,7 @@  #define IDREMOVE                        3  #define IDI_LL_ICON                     103  #define IDC_GRABHAND                    104 +#define IDI_LL_ICON_SMALL               105  #define IDC_CURSOR1                     134  #define IDC_CURSOR2                     136  #define IDC_CURSOR3                     147 diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 4ee26a312a..dc2ba5f171 100755 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -56,6 +56,7 @@ END  // remains consistent on all systems.  IDI_LL_ICON             ICON                    "ll_icon.ico"  IDI_LCD_LL_ICON         ICON                    "icon1.ico" +IDI_LL_ICON_SMALL       ICON                    "ll_icon_small.ico"  /////////////////////////////////////////////////////////////////////////////  // diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 97468c3b2e..ebc4beead2 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -655,7 +655,6 @@ with the same filename but different name    <texture name="login_sl_logo"  file_name="windows/login_sl_logo.png" preload="true" />    <texture name="login_sl_logo_small"  file_name="windows/login_sl_logo_small.png" preload="true" /> -  <texture name="first_login_image"  file_name="windows/first_login_image.jpg" preload="true" />    <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" />    <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" /> diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpgBinary files differ deleted file mode 100644 index 30f31341ed..0000000000 --- a/indra/newview/skins/default/textures/windows/first_login_image.jpg +++ /dev/null diff --git a/indra/newview/skins/default/xui/de/panel_login_first.xml b/indra/newview/skins/default/xui/de/panel_login_first.xml deleted file mode 100644 index 038001157e..0000000000 --- a/indra/newview/skins/default/xui/de/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		http://secondlife.com/account/request.php?lang=de -	</panel.string> -	<panel.string name="sign_up_url"> -		https://join.secondlife.com/ -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="Benutzername" name="username_combo" tool_tip="Bei der Registrierung gewählter Benutzername wie „berndschmidt12“ oder „Liebe Sonne“"/> -					<line_editor label="Kennwort" name="password_edit"/> -					<button label="Anmelden" name="connect_btn"/> -					<check_box label="Details speichern" name="remember_check"/> -					<text name="forgot_password_text"> -						Kennwort vergessen -					</text> -					<text name="sign_up_text"> -						Registrieren -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						Ihr erster Schritt ist Learning Island. Suchen Sie die Pforte! -					</text> -					<text name="image_caption_right"> -						Erkunden Sie dann Social Island und lernen Sie andere Einwohner kennen! -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/floater_test_slapp.xml b/indra/newview/skins/default/xui/en/floater_test_slapp.xml index dd2720816a..5a13a0147e 100644 --- a/indra/newview/skins/default/xui/en/floater_test_slapp.xml +++ b/indra/newview/skins/default/xui/en/floater_test_slapp.xml @@ -8,7 +8,7 @@   width="500">     <floater.string      name="remove_folder_slapp"> -    secondlife://app/remove_folder/?folder_id= +    secondlife:///app/remove_folder/?folder_id=     </floater.string>     <text      type="string" @@ -42,7 +42,7 @@      width="450"      layout="topleft"      left="16"> -        secondlife://app/wear_folder/?folder_name=Daisy +        secondlife:///app/wear_folder/?folder_name=Daisy     </text>     <text      type="string" @@ -63,7 +63,7 @@      width="450"      layout="topleft"      left="16"> -        secondlife://app/add_folder/?folder_name=Cardboard%20Boxbot +        secondlife:///app/add_folder/?folder_name=Cardboard%20Boxbot     </text>     <text      type="string" @@ -73,7 +73,7 @@      height="16"      width="450"      layout="topleft"> -        secondlife://app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8 +        secondlife:///app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8     </text>     <text      type="string" @@ -118,6 +118,6 @@      name="remove_folder_txt"      layout="topleft"      left="16"> -        secondlife://app/remove_folder/?folder_id= +        secondlife:///app/remove_folder/?folder_id=     </text>  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_url_parcel.xml b/indra/newview/skins/default/xui/en/menu_url_parcel.xml index e0f1fcf9c3..95752dab66 100644 --- a/indra/newview/skins/default/xui/en/menu_url_parcel.xml +++ b/indra/newview/skins/default/xui/en/menu_url_parcel.xml @@ -16,7 +16,7 @@       layout="topleft"       name="show_on_map">          <menu_item_call.on_click -         function="Url.ShowOnMap" /> +         function="Url.ShowParcelOnMap" />      </menu_item_call>      <menu_item_separator       layout="topleft" /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a7e892f6f2..f76f9cc96c 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12636,4 +12636,15 @@ are wearing now.      Unable to apply material to the water exclusion surface.      <tag>fail</tag>    </notification> + +  <notification +   icon="notify.tga" +   name="ImageUploadResized" +   type="alertmodal"> +      The texture you are uploading has been resized from [ORIGINAL_WIDTH]x[ORIGINAL_HEIGHT] to [NEW_WIDTH]x[NEW_HEIGHT] in order to to fit the maximum size of [MAX_WIDTH]x[MAX_HEIGHT] pixels. +      <usetemplate +          ignoretext="Image Upload Resized" +          name="okignore" +          yestext="OK"/> +  </notification>  </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml deleted file mode 100644 index d6ac71db94..0000000000 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ /dev/null @@ -1,262 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel -  follows="all" -  height="768" -  layout="topleft" -  name="panel_login" -  focus_root="true" -  background_visible="true" -  bg_opaque_color="0.16 0.16 0.16 1" -  background_opaque="true" -  width="1024"> -  <panel.string -    name="forgot_password_url"> -    http://secondlife.com/account/request.php -  </panel.string> -  <panel.string -    name="sign_up_url"> -    https://join.secondlife.com/ -  </panel.string> -  <layout_stack -    follows="left|right|top|bottom" -    width="1024" -    height="768" -    left="0" -    name="logo_stack" -    orientation="vertical" -    top="0"> -    <layout_panel -      height="18" -      auto_resize="false" -      name="page_top" -      width="1024" /> -    <!-- start of logo stack --> -    <layout_panel -      height="130" -      min_height="10" -      auto_resize="false" -      name="parent_panel" -      width="1024"> -      <layout_stack -        follows="left|right|top|bottom" -        height="100" -        left="0" -        name="logo_stack" -        orientation="horizontal" -        top="0" -        width="1024"> -        <layout_panel -          height="110" -          min_height="10" -          auto_resize="true" -          name="logo_left" -          width="300" /> -        <layout_panel -          auto_resize="false" -          follows="left|right|top" -          name="logo_container" -          width="225" -          left="0" -          top="0" -          height="105"> -          <icon -            height="94" -            image_name="login_sl_logo" -            left="0" -            name="sl_logo" -            top="0" /> -        </layout_panel> -        <layout_panel -          height="100" -          name="logo_right" -          auto_resize="true" -          width="300" /> -      </layout_stack> -    </layout_panel> -    <!-- end of logo stack --> -    <!-- start of widget stack --> -    <layout_panel -      height="100" -      min_height="10" -      auto_resize="false" -      name="parent_panel2" -      width="1024"> -      <layout_stack -        follows="left|right|top|bottom" -        height="80" -        left="0" -        name="widget_stack" -        orientation="horizontal" -        top="0" -        width="1024"> -        <layout_panel -          height="80" -          min_height="10" -          auto_resize="true" -          name="widget_left" -          width="200" /> -        <layout_panel -          auto_resize="false" -          follows="left|right|top" -          name="widget_container" -          width="730" -          left="0" -          top="0" -          height="80"> -          <combo_box -            allow_text_entry="true" -            follows="left|bottom" -            height="32" -            left="42" -            label="Username" -            combo_editor.font="SansSerifLarge" -            max_chars="128" -            top="0" -            combo_editor.prevalidator="ascii" -            tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" -            name="username_combo" -            width="232"> -            <combo_box.combo_editor -                text_pad_left="8" /> -            <combo_box.combo_button -                visible ="false"/> -              <combo_box.drop_down_button -                visible ="false"/> -          </combo_box> -          <line_editor -            follows="left|top" -            width="200" -            height="32" -            left="262" -            max_length_chars="16" -            name="password_edit" -            label="Password" -            text_pad_left="8" -            font="SansSerifLarge" -            is_password="true" -            select_on_focus="true" -            commit_on_focus_lost="false" -            top="0" /> -          <button -            follows="left|top" -            image_unselected="PushButton_Login" -            image_pressed="PushButton_Login_Pressed" -            image_hover_unselected="PushButton_Login_Over" -            label="Log In" -            label_color="White" -            font="SansSerifLarge" -            name="connect_btn" -  	        left_pad="15" -            width="120" -            height="32" -            top="0" /> -          <text -            follows="left|top" -            font="SansSerifLarge" -            font.style="BOLD" -            text_color="EmphasisColor" -            height="34" -            name="sign_up_text" -            left_pad="10" -            top="0" -            width="200" -            valign="center"> -            Sign up -          </text> -          <check_box -            follows="left|top" -            font="SansSerifLarge" -            left="42" -            top="32" -            height="24" -            label="Remember me" -            word_wrap="down" -            check_button.bottom="3" -            name="remember_name" -            tool_tip="Already remembered user can be forgotten from Me > Preferences > Advanced > Remembered Usernames." -            width="198" /> -          <check_box -            control_name="RememberPassword" -            follows="left|top" -            font="SansSerifLarge" -            height="24" -            left="262" -            bottom_delta="0" -            label="Remember password" -            word_wrap="down" -            check_button.bottom="3" -            name="remember_password" -            width="198" /> -          <text -            follows="left|top" -            font="SansSerifLarge" -            text_color="EmphasisColor" -            height="16" -            name="forgot_password_text" -            left="492" -            top="34" -            width="200"> -            Forgotten password -          </text> -        </layout_panel> -        <layout_panel -          height="100" -          name="widget_right" -          auto_resize="true" -          width="200" /> -      </layout_stack> -    </layout_panel> -    <!-- end of widget stack --> -    <!-- start of images stack --> -    <layout_panel -      height="500" -      min_height="10" -      auto_resize="false" -      name="parent_panel3" -      width="1024"> -      <layout_stack -        follows="left|right|top|bottom" -        height="500" -        left="0" -        name="images_stack" -        orientation="horizontal" -        top="0" -        width="1024"> -        <layout_panel -          height="500" -          min_height="10" -          auto_resize="true" -          name="images_left" -          width="96" /> -        <layout_panel -          auto_resize="false" -          follows="left|right|top" -          name="images_container" -          width="675" -          left="0" -          top="0" -          height="500"> -          <icon -            height="450" -            width="675" -            image_name="first_login_image" -            left="0" -            name="image_left" -            top="0" /> -        </layout_panel> -        <layout_panel -          height="100" -          name="images_right" -          auto_resize="true" -          width="96" /> -      </layout_stack> -    </layout_panel> -    <!-- end of images stack --> -    <layout_panel -      height="400" -      min_height="10" -      auto_resize="true" -      name="page_bottom" -      width="1024" /> -  </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 8051ffa8ec..86999b1afb 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -32,15 +32,15 @@     height="23"     increment="64"     initial_value="1024" -   label="Cache size (256 - 9984MB)" +   label="Cache size (896 - 32768MB)"     label_width="150"     layout="topleft"     left="80" -   max_val="9984" -   min_val="256" +   max_val="32768" +   min_val="896"     top_pad="10"     name="cachesizespinner" -   width="200" /> +   width="210" />    <text     type="string"     length="1" @@ -59,7 +59,7 @@     label="Clear Cache"     label_selected="Clear Cache"     layout="topleft" -   left_pad="30" +   left_pad="20"     name="clear_cache"     top_delta="0"     width="100"> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 5041fb4878..1c00837073 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -1,15 +1,31 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel +  <panel      border="true"      follows="left|top|right|bottom" -    height="408" -    label="Communication" +    height="438" +    label="Privacy"      layout="topleft"      left="102" -    name="im" +    name="Privacy panel"      top="1"      width="517"> +  <tab_container +    top_pad="0" +    enabled="true" +    follows="left|top" +    height="430" +    width="517" +    left_delta="0" +    name="privacy_tab_container" +    tab_position="top" +    tab_stop="false"> +  <panel +    label="General" +    name="privacy_preferences_general" +    layout="topleft" +    follows="top|left"> +    <panel.string        name="log_in_to_change">      log in to change @@ -63,7 +79,7 @@        name="online_visibility"        top_pad="30"        width="350" /> -     +      <check_box       enabled_control="EnableVoiceChat"       control_name="AutoDisengageMic" @@ -74,6 +90,37 @@       name="auto_disengage_mic_check"       top_pad="10"       width="350" /> +    <check_box +     control_name="EnableLookAtTarget" +     height="16" +     label="Enable LookAt" +     tool_tip="Enable tracking cursor position with avatar head's rotation" +     layout="topleft" +     left="30" +     name="enable_lookat_target" +     top_pad="10" +     width="350" /> +    <check_box +     enabled_control="EnableLookAtTarget" +     control_name="LimitLookAtTarget" +     height="16" +     label="Limit LookAt Distance" +     tool_tip="Limit the look at target's distance by restricting it around the avatar's head" +     layout="topleft" +     left="50" +     name="limit_lookat_distance" +     top_pad="10" +     width="350" /> +    <check_box +     control_name="EnableSelectionHints" +     height="16" +     label="Enable Selection Hints" +     tool_tip="Enable reporting and tracking current selection using 'beam' particles and character animations" +     layout="topleft" +     left="30" +     name="enable_selection_hints" +     top_pad="10" +     width="350" />      <button       follows="left|top"       height="23" @@ -103,3 +150,48 @@         (People and/or Objects you have blocked)      </text>      </panel> + +    <panel +      label="Discord" +      name="privacy_preferences_discord" +      layout="topleft" +      follows="top|left"> + +      <check_box +        control_name="EnableDiscord" +        height="16" +        enabled="true" +        label="Enable Discord integration" +        layout="topleft" +        left="30" +        name="enable_discord" +        top_pad="20" +        width="350" /> + +      <check_box +        enabled_control="EnableDiscord" +        control_name="ShowDiscordActivityDetails" +        height="16" +        enabled="true" +        label="Show avatar name" +        layout="topleft" +        left="30" +        name="show_name" +        top_pad="20" +        width="350" /> + +      <check_box +        enabled_control="EnableDiscord" +        control_name="ShowDiscordActivityState" +        height="16" +        enabled="false" +        label="Show location" +        layout="topleft" +        left="30" +        name="show_location" +        top_pad="20" +        width="350" /> +      </panel> +  </tab_container> + +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 4501e0df3a..cf52916484 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -86,7 +86,7 @@       height="18"       left="0"        name="balance" -     tool_tip="Click to refresh your L$ balance" +     tool_tip="L$ [AMT]
Click to refresh your L$ balance.
Double-click to display or hide your L$ balance."       v_pad="4"       top="0"       wrap="false"  diff --git a/indra/newview/skins/default/xui/es/panel_login_first.xml b/indra/newview/skins/default/xui/es/panel_login_first.xml deleted file mode 100644 index ccb6858351..0000000000 --- a/indra/newview/skins/default/xui/es/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		http://secondlife.com/account/request.php?lang=es -	</panel.string> -	<panel.string name="sign_up_url"> -		https://join.secondlife.com/ -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="Nombre de usuario" name="username_combo" tool_tip="El nombre de usuario que elegiste al registrarte, como bobsmith12 o Steller Sunshine"/> -					<line_editor label="Contraseña" name="password_edit"/> -					<button label="Iniciar sesión" name="connect_btn"/> -					<check_box label="Recordarme" name="remember_check"/> -					<text name="forgot_password_text"> -						Contraseña olvidada -					</text> -					<text name="sign_up_text"> -						Regístrate -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						Tu primer destino es la Isla de aprendizaje. ¡Encuentra el portal de salida! -					</text> -					<text name="image_caption_right"> -						A continuación, puedes explorar la Isla social y hablar con otros residentes nuevos. -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_login_first.xml b/indra/newview/skins/default/xui/fr/panel_login_first.xml deleted file mode 100644 index 8f40d0230c..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		http://secondlife.com/account/request.php?lang=fr -	</panel.string> -	<panel.string name="sign_up_url"> -		https://join.secondlife.com/ -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="Nom d'utilisateur" name="username_combo" tool_tip="Nom d'utilisateur que vous avez choisi lors de votre inscription (par exemple, bobsmith12 ou Steller Sunshine)."/> -					<line_editor label="Mot de passe" name="password_edit"/> -					<button label="Connexion" name="connect_btn"/> -					<check_box font="SansSerifSmall" label="Mémoriser mes informations" name="remember_check"/> -					<text name="forgot_password_text"> -						Mot de passe oublié -					</text> -					<text name="sign_up_text"> -						S'inscrire -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						Votre première étape est Learning Island. Trouvez le portail de sortie. -					</text> -					<text name="image_caption_right"> -						Puis explorez Social Island et faites la connaissance d'autres résidents. -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_login_first.xml b/indra/newview/skins/default/xui/it/panel_login_first.xml deleted file mode 100644 index 5b04fd411a..0000000000 --- a/indra/newview/skins/default/xui/it/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		http://secondlife.com/account/request.php?lang=it -	</panel.string> -	<panel.string name="sign_up_url"> -		http://join.secondlife.com/ -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="Nome utente" name="username_combo" tool_tip="Il nome utente che hai scelto durante la registrazione, come roby12 o Stella Solare"/> -					<line_editor label="Password" name="password_edit"/> -					<button label="Accedi" name="connect_btn"/> -					<check_box label="Ricordami" name="remember_check"/> -					<text name="forgot_password_text"> -						Password dimenticata -					</text> -					<text name="sign_up_text"> -						Registrati -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						Il primo passo è a Learning Island. Trova il portale di uscita! -					</text> -					<text name="image_caption_right"> -						Quindi esplora Social Island e incontra altri nuovi residenti. -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_login_first.xml b/indra/newview/skins/default/xui/ja/panel_login_first.xml deleted file mode 100644 index 0f987fc816..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_login_first.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		https://secondlife.com/my/account/request.php?lang=ja-JP -	</panel.string> -	<panel.string name="sign_up_url"> -		https://join.secondlife.com/?lang=ja -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="page_top"/> -		<layout_panel name="parent_panel"> -			<layout_stack name="logo_stack"> -				<layout_panel name="logo_left"/> -				<layout_panel name="logo_container"> -					<icon name="sl_logo"/> -				</layout_panel> -				<layout_panel auto_resize="true"/> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_left"/> -				<layout_panel name="widget_container"> -					<combo_box label="ユーザ名" tool_tip="登録時に自分で選んだユーザー名(例:bobsmith12、Steller Sunshineなど)" name="username_combo"> -						<combo_box.combo_editor/> -						<combo_box.combo_button/> -						<combo_box.drop_down_button/> -					</combo_box> -					<line_editor name="password_edit" label="パスワード"/> -					<button label="ログイン" name="connect_btn"/> -					<text name="sign_up_text" valign="center"> -						サインアップ -					</text> -					<check_box label="ユーザ名を記憶" name="remember_name" tool_tip="すでに記憶されているユーザーは、「私」>「初期設定」>「詳細設定」>「記憶されたユーザー名」から削除できます。"/> -					<check_box label="パスワード記憶" name="remember_password"/> -					<text name="forgot_password_text"> -						パスワードを忘れましたか? -					</text> -				</layout_panel> -				<layout_panel name="widget_right"/> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_left"/> -				<layout_panel name="images_container"> -					<icon name="image_left"/> -				</layout_panel> -				<layout_panel name="images_right"/> -			</layout_stack> -		</layout_panel> -		<layout_panel name="page_bottom"/> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pl/panel_login_first.xml b/indra/newview/skins/default/xui/pl/panel_login_first.xml deleted file mode 100644 index 0604ecbcff..0000000000 --- a/indra/newview/skins/default/xui/pl/panel_login_first.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="panel_login"> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="Użytkownik" tool_tip="Nazwa użytkownika wybrana przy rejestracji, np. bobsmith12 lub Steller Sunshine" name="username_combo" /> -					<line_editor name="password_edit" label="Hasło" /> -					<button label="Zaloguj" name="connect_btn" /> -					<check_box label="Zapamiętaj mnie" name="remember_check" /> -					<text name="forgot_password_text"> -						Zapomniałem/am hasła -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						Wyspa Nauki to Twój pierwszy krok. Znajdź portal z wyjściem! -					</text> -					<text name="image_caption_right"> -						Potem zwiedź Wyspę Towarzyską i poznaj innych nowych rezydentów! -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_login_first.xml b/indra/newview/skins/default/xui/pt/panel_login_first.xml deleted file mode 100644 index 86c61163bc..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		http://secondlife.com/account/request.php?lang=pt -	</panel.string> -	<panel.string name="sign_up_url"> -		https://join.secondlife.com/ -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="Nome de usuário" name="username_combo" tool_tip="O nome de usuário que você escolheu ao fazer seu cadastro, como zecazc12 ou Magia Solar"/> -					<line_editor label="Senha" name="password_edit"/> -					<button label="Login" name="connect_btn"/> -					<check_box label="Lembrar-me" name="remember_check"/> -					<text name="forgot_password_text"> -						Senha esquecida -					</text> -					<text name="sign_up_text"> -						Cadastre-se -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						Sua primeira parada é a Ilha da Educação. Encontre o portal de saída! -					</text> -					<text name="image_caption_right"> -						Em seguida, explore a Ilha Social e encontre novos residentes! -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_login_first.xml b/indra/newview/skins/default/xui/ru/panel_login_first.xml deleted file mode 100644 index 5db81ea7ca..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		http://secondlife.com/account/request.php -	</panel.string> -	<panel.string name="sign_up_url"> -		https://join.secondlife.com/ -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="Имя пользователя" name="username_combo" tool_tip="Имя пользователя, которое вы выбрали при регистрации, например, «bobsmith12» или «Steller Sunshine»"/> -					<line_editor label="Пароль" name="password_edit"/> -					<button label="Войти" name="connect_btn"/> -					<check_box label="Запомнить меня" name="remember_check"/> -					<text name="forgot_password_text"> -						Забытый пароль -					</text> -					<text name="sign_up_text"> -						Регистрация -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						Ваш первый шаг – Учебный остров. Найдите портал выхода! -					</text> -					<text name="image_caption_right"> -						Затем исследуйте Социальный остров и познакомьтесь с другими новичками! -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_login_first.xml b/indra/newview/skins/default/xui/tr/panel_login_first.xml deleted file mode 100644 index 1fc80c2b97..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		http://secondlife.com/account/request.php -	</panel.string> -	<panel.string name="sign_up_url"> -		https://join.secondlife.com/ -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="Kullanıcı Adı" name="username_combo" tool_tip="Kaydolduğunuzda seçtiğiniz kullanıcı adı, örn. mustafayalcin12 veya Faruk Gungoren"/> -					<line_editor label="Parola" name="password_edit"/> -					<button label="Oturum Aç" name="connect_btn"/> -					<check_box label="Beni hatırla" name="remember_check"/> -					<text name="forgot_password_text"> -						Parolamı unuttum -					</text> -					<text name="sign_up_text"> -						Kaydol -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						Başlangıç yeriniz Eğitim Adası. Haydi çıkış portalını bulun! -					</text> -					<text name="image_caption_right"> -						Sonra da Sosyal Ada'yı keşfe çıkın ve diğer LS sakinleriyle tanışın! -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_login_first.xml b/indra/newview/skins/default/xui/zh/panel_login_first.xml deleted file mode 100644 index 4d72fcdd03..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> -	<panel.string name="forgot_password_url"> -		http://secondlife.com/account/request.php -	</panel.string> -	<panel.string name="sign_up_url"> -		http://join.secondlife.com/ -	</panel.string> -	<layout_stack name="logo_stack"> -		<layout_panel name="parent_panel2"> -			<layout_stack name="widget_stack"> -				<layout_panel name="widget_container"> -					<combo_box label="使用者名稱" name="username_combo" tool_tip="使用者名稱是你註冊時所挑選的,例如 bobsmith12 或 Steller Sunshine"/> -					<line_editor label="密碼" name="password_edit"/> -					<button label="登入" name="connect_btn"/> -					<check_box label="記得我" name="remember_check"/> -					<text name="forgot_password_text"> -						忘記密碼 -					</text> -					<text name="sign_up_text"> -						註冊 -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -		<layout_panel name="parent_panel3"> -			<layout_stack name="images_stack"> -				<layout_panel name="images_container"> -					<text name="image_caption_left"> -						你在「學習島」的第一步。 找到離開的傳送門! -					</text> -					<text name="image_caption_right"> -						接著,到「社交島」探索,認識新的居民朋友! -					</text> -				</layout_panel> -			</layout_stack> -		</layout_panel> -	</layout_stack> -</panel> diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index d5e281bba8..10c68432a1 100644 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -43,12 +43,15 @@ namespace LLStatViewer      LLTrace::SampleStatHandle<>     FPS_SAMPLE("fpssample");  } -void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars) +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars)  {      counts.resize(3);      counts[0] = 0;      counts[1] = 0;      counts[2] = 1; +    cloud_avatars = 0; +    pending_meshes = 0; +    control_avatars = 0;  }  // static diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index cada4a2cd6..04c3fea93a 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -149,7 +149,6 @@ class ViewerManifest(LLManifest):              with self.prefix(src_dst="skins"):                      # include the entire textures directory recursively                      with self.prefix(src_dst="*/textures"): -                            self.path("*/*.jpg")                              self.path("*/*.png")                              self.path("*.tga")                              self.path("*.j2c") @@ -557,6 +556,9 @@ class Windows_x86_64_Manifest(ViewerManifest):              ):                  self.path(libfile) +            if self.args['discord'] == 'ON': +                self.path("discord_partner_sdk.dll") +              if self.args['openal'] == 'ON':                  # Get openal dll                  self.path("OpenAL32.dll") @@ -1019,6 +1021,13 @@ class Darwin_x86_64_Manifest(ViewerManifest):                                  ):                      self.path2basename(relpkgdir, libfile) +                # Discord social SDK +                if self.args['discord'] == 'ON': +                    for libfile in ( +                                "libdiscord_partner_sdk.dylib", +                                ): +                        self.path2basename(relpkgdir, libfile) +                  # OpenAL dylibs                  if self.args['openal'] == 'ON':                      for libfile in ( @@ -1385,6 +1394,7 @@ if __name__ == "__main__":      extra_arguments = [          dict(name='bugsplat', description="""BugSplat database to which to post crashes,               if BugSplat crash reporting is desired""", default=''), +        dict(name='discord', description="""Indication discord social sdk libraries are needed""", default='OFF'),          dict(name='openal', description="""Indication openal libraries are needed""", default='OFF'),          dict(name='tracy', description="""Indication tracy profiler is enabled""", default='OFF'),          ] | 
