diff options
| author | Erik Kundiman <erik@megapahit.org> | 2026-09-05 00:17:50 +0800 |
|---|---|---|
| committer | Erik Kundiman <erik@megapahit.org> | 2026-09-05 00:17:50 +0800 |
| commit | 11cab7b55c64bdc59d0780aacd853e5c12d6adab (patch) | |
| tree | 16f138566459efc960250b4a3dc87c664437549f /indra/newview | |
| parent | a0770adb8bda13e8daa2190a8f95972055983b0d (diff) | |
| parent | 79b07e64267386396f6b122c5ced12eda513c72e (diff) | |
Merge tag 'Second_Life_Release#79b07e64-26.4' into 26.426.4
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 24 | ||||
| -rw-r--r-- | indra/newview/llbuycurrencyhtml.cpp | 63 | ||||
| -rw-r--r-- | indra/newview/llbuycurrencyhtml.h | 11 | ||||
| -rw-r--r-- | indra/newview/llfloaterbuycurrencyhtml.cpp | 152 | ||||
| -rw-r--r-- | indra/newview/llfloaterbuycurrencyhtml.h | 42 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_buy_currency_html.xml | 17 |
7 files changed, 187 insertions, 124 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index cacaa605be..3b067b7a61 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1194,6 +1194,28 @@ <key>Value</key> <integer>1</integer> </map> + <key>BuyCurrencyHTML</key> + <map> + <key>Comment</key> + <string>Use HTML based L$ packs floater instead of legacy XUI version</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>BuyCurrencyPacksURL</key> + <map> + <key>Comment</key> + <string>URL for the L$ packs purchase floater</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>https://accounts.secondlife.com/packs/floater?lang=[LANGUAGE]&shortfall=[SHORTFALL]</string> + </map> <key>EnableButtonFlashing</key> <map> <key>Comment</key> @@ -7377,7 +7399,7 @@ <key>QuickBuyCurrency</key> <map> <key>Comment</key> - <string>Toggle between HTML based currency purchase floater and legacy XUI version</string> + <string>(Deprecated) Use BuyCurrencyHTML instead</string> <key>Persist</key> <integer>1</integer> <key>Type</key> diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp index e6c4d44573..9ad068cf7f 100644 --- a/indra/newview/llbuycurrencyhtml.cpp +++ b/indra/newview/llbuycurrencyhtml.cpp @@ -34,6 +34,8 @@ #include "llcommandhandler.h" #include "llviewercontrol.h" #include "llstatusbar.h" +#include "llcorehttputil.h" +#include "llcoros.h" // support for secondlife:///app/buycurrencyhtml/{ACTION}/{NEXT_ACTION}/{RETURN_CODE} SLapps class LLBuyCurrencyHTMLHandler : @@ -86,53 +88,85 @@ public: }; LLBuyCurrencyHTMLHandler gBuyCurrencyHTMLHandler; +bool LLBuyCurrencyHTML::sWebFloaterEnabled = false; + +//////////////////////////////////////////////////////////////////////////////// +// static +static void checkFeatureFlag_coro(std::string check_url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter = std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("CheckBuyCurrencyURL", httpPolicy); + LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>(); + + LLCore::HttpOptions::ptr_t httpOptions = std::make_shared<LLCore::HttpOptions>(); + httpOptions->setRetries(0); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, check_url, httpOptions); + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + LLBuyCurrencyHTML::sWebFloaterEnabled = !(status.isHttpStatus() && status.getType() == 501); +} + +// static +void LLBuyCurrencyHTML::checkFeatureFlag() +{ + std::string check_url = LLFloaterBuyCurrencyHTML::buildURL(); + LLCoros::instance().launch("checkFeatureFlag_coro", + [check_url]() { checkFeatureFlag_coro(check_url); }); +} + //////////////////////////////////////////////////////////////////////////////// // static // Opens the legacy XUI based floater or new HTML based one based on -// the QuickBuyCurrency value in settings.xml - this overload is for +// the BuyCurrencyHTML value in settings.xml - this overload is for // the case where the amount is not requested. void LLBuyCurrencyHTML::openCurrencyFloater() { - if ( gSavedSettings.getBOOL( "QuickBuyCurrency" ) ) + if (gSavedSettings.getBOOL("BuyCurrencyHTML") && sWebFloaterEnabled) { - // HTML version - LLBuyCurrencyHTML::showDialog( false, "", 0 ); + LLBuyCurrencyHTML::showDialog(); } else { // legacy version LLFloaterBuyCurrency::buyCurrency(); - }; + } } //////////////////////////////////////////////////////////////////////////////// // static // Opens the legacy XUI based floater or new HTML based one based on -// the QuickBuyCurrency value in settings.xml - this overload is for +// the BuyCurrencyHTML value in settings.xml - this overload is for // the case where the amount and a string to display are requested. void LLBuyCurrencyHTML::openCurrencyFloater( const std::string& message, S32 sum ) { - if ( gSavedSettings.getBOOL( "QuickBuyCurrency" ) ) + if (gSavedSettings.getBOOL("BuyCurrencyHTML") && sWebFloaterEnabled) { - // HTML version - LLBuyCurrencyHTML::showDialog( true, message, sum ); + LLBuyCurrencyHTML::showDialog(sum - gStatusBar->getBalance()); + LLFloaterBuyCurrencyHTML* floater = dynamic_cast<LLFloaterBuyCurrencyHTML*>(LLFloaterReg::getInstance("buy_currency_html")); + if (floater) + { + floater->setFallbackContext(message, sum); + } } else { // legacy version LLFloaterBuyCurrency::buyCurrency( message, sum ); - }; + } } //////////////////////////////////////////////////////////////////////////////// // static -void LLBuyCurrencyHTML::showDialog( bool specific_sum_requested, const std::string& message, S32 sum ) +void LLBuyCurrencyHTML::showDialog(S32 shortfall) { LLFloaterBuyCurrencyHTML* buy_currency_floater = dynamic_cast< LLFloaterBuyCurrencyHTML* >( LLFloaterReg::getInstance( "buy_currency_html" ) ); if ( buy_currency_floater ) { // pass on flag indicating if we want to buy specific amount and if so, how much - buy_currency_floater->setParams( specific_sum_requested, message, sum ); + buy_currency_floater->setShortfall(shortfall); // force navigate to new URL buy_currency_floater->navigateToFinalURL(); @@ -144,7 +178,7 @@ void LLBuyCurrencyHTML::showDialog( bool specific_sum_requested, const std::stri buy_currency_floater->setFrontmost( take_focus ); // spec calls for floater to be centered on client window - buy_currency_floater->center(); + //buy_currency_floater->center(); } else { @@ -161,7 +195,4 @@ void LLBuyCurrencyHTML::closeDialog() { buy_currency_floater->closeFloater(); }; - - // Update L$ balance in the status bar in case L$ were purchased - LLStatusBar::sendMoneyBalanceRequest(); } diff --git a/indra/newview/llbuycurrencyhtml.h b/indra/newview/llbuycurrencyhtml.h index 5e3d30dcd0..2f78199dcb 100644 --- a/indra/newview/llbuycurrencyhtml.h +++ b/indra/newview/llbuycurrencyhtml.h @@ -29,8 +29,6 @@ #include "llsingleton.h" -class LLFloaterBuyCurrencyHTML; - class LLBuyCurrencyHTML { public: @@ -41,11 +39,16 @@ class LLBuyCurrencyHTML static void openCurrencyFloater( const std::string& message, S32 sum ); // show and give focus to actual currency floater - this is used for both cases - // where the sum is required and where it is not - static void showDialog( bool specific_sum_requested, const std::string& message, S32 sum ); + // where the shortfall is required and where it is not + static void showDialog( S32 shortfall = 0 ); // close (and destroy) the currency floater static void closeDialog(); + + // probe BuyCurrencyPacksURL once at login; clears sWebFloaterEnabled if 501 + static void checkFeatureFlag(); + + static bool sWebFloaterEnabled; }; #endif // LL_LLBUYCURRENCYHTML_H diff --git a/indra/newview/llfloaterbuycurrencyhtml.cpp b/indra/newview/llfloaterbuycurrencyhtml.cpp index d3712869b0..55b7c32169 100644 --- a/indra/newview/llfloaterbuycurrencyhtml.cpp +++ b/indra/newview/llfloaterbuycurrencyhtml.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2026, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,97 +27,105 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterbuycurrencyhtml.h" -#include "llhttpconstants.h" +#include "llfloaterbuycurrency.h" +#include "llmediactrl.h" #include "llstatusbar.h" +#include "llviewercontrol.h" +#include "llweb.h" -//////////////////////////////////////////////////////////////////////////////// -// -LLFloaterBuyCurrencyHTML::LLFloaterBuyCurrencyHTML( const LLSD& key ): - LLFloater( key ), - mSpecificSumRequested( false ), - mMessage( "" ), - mSum( 0 ) + +LLFloaterBuyCurrencyHTML::LLFloaterBuyCurrencyHTML(const LLSD& key) + : LLFloater(key), + mBrowser(nullptr) { } -//////////////////////////////////////////////////////////////////////////////// -// -bool LLFloaterBuyCurrencyHTML::postBuild() +LLFloaterBuyCurrencyHTML::~LLFloaterBuyCurrencyHTML() { - // observer media events - mBrowser = getChild<LLMediaCtrl>( "browser" ); - mBrowser->addObserver( this ); - - return true; } -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterBuyCurrencyHTML::navigateToFinalURL() +void LLFloaterBuyCurrencyHTML::onClose(bool app_quitting) { - // URL for actual currency buy contents is in XUI file - std::string buy_currency_url = getString( "buy_currency_url" ); - - // replace [LANGUAGE] meta-tag with view language - LLStringUtil::format_map_t replace; - - // viewer language - replace[ "[LANGUAGE]" ] = LLUI::getLanguage(); - - // flag that specific amount requested - replace[ "[SPECIFIC_AMOUNT]" ] = ( mSpecificSumRequested ? "y":"n" ); - - // amount requested - std::ostringstream codec( "" ); - codec << mSum; - replace[ "[SUM]" ] = codec.str(); - - // users' current balance - codec.clear(); - codec.str( "" ); - codec << gStatusBar->getBalance(); - replace[ "[BAL]" ] = codec.str(); - - // message - "This cost L$x,xxx for example - replace[ "[MSG]" ] = LLURI::escape( mMessage ); - LLStringUtil::format( buy_currency_url, replace ); + if (!app_quitting) + LLStatusBar::sendMoneyBalanceRequest(); - // write final URL to debug console - LL_INFOS() << "Buy currency HTML parsed URL is " << buy_currency_url << LL_ENDL; + LLFloater::onClose(app_quitting); +} - // kick off the navigation - mBrowser->navigateTo( buy_currency_url, HTTP_CONTENT_TEXT_HTML ); +bool LLFloaterBuyCurrencyHTML::postBuild() +{ + mBrowser = getChild<LLMediaCtrl>("browser"); + mBrowser->addObserver(this); + mBrowser->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); + LLViewerMedia::getInstance()->getOpenIDCookie(mBrowser); + return true; } -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterBuyCurrencyHTML::handleMediaEvent( LLPluginClassMedia* self, EMediaEvent event ) +// static +std::string LLFloaterBuyCurrencyHTML::buildURL(S32 shortfall) { - // placeholder for now - just in case we want to catch media events - if ( LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE == event ) + std::string url = gSavedSettings.getString("BuyCurrencyPacksURL"); + LLStringUtil::format_map_t replace; + replace["[LANGUAGE]"] = LLUI::getLanguage(); + if (shortfall > 0) { - // update currency after we complete a navigation since there are many ways - // this can result in a different L$ balance - LLStatusBar::sendMoneyBalanceRequest(); - }; + replace["[SHORTFALL]"] = std::to_string(shortfall); + } + LLStringUtil::format(url, replace); + if (shortfall <= 0) + { + LLStringUtil::replaceString(url, "&shortfall=[SHORTFALL]", ""); + } + return url; } -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterBuyCurrencyHTML::onClose( bool app_quitting ) +void LLFloaterBuyCurrencyHTML::navigateToFinalURL() { - // Update L$ balance one more time - LLStatusBar::sendMoneyBalanceRequest(); + mBrowser->navigateTo(buildURL(mShortfall), HTTP_CONTENT_TEXT_HTML); +} - destroy(); +void LLFloaterBuyCurrencyHTML::setFallbackContext(const std::string& message, S32 sum) +{ + mFallbackMessage = message; + mFallbackSum = sum; + mHasFallbackTarget = true; } -//////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterBuyCurrencyHTML::setParams( bool specific_sum_requested, const std::string& message, S32 sum ) +void LLFloaterBuyCurrencyHTML::fallbackToLegacy() { - // save these away - used to construct URL later - mSpecificSumRequested = specific_sum_requested; - mMessage = message; - mSum = sum; + LL_WARNS() << "Buy Currency HTML page failed to load, falling back to legacy floater" << LL_ENDL; + closeFloater(); + if (mHasFallbackTarget) + { + LLFloaterBuyCurrency::buyCurrency(mFallbackMessage, mFallbackSum); + } + else + { + LLFloaterBuyCurrency::buyCurrency(); + } +} + +void LLFloaterBuyCurrencyHTML::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) +{ + if (LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE == event) + { + if (self->getNavigateURI().find("done=success") != std::string::npos) + { + LLStatusBar::sendMoneyBalanceRequest(); + } + else + { + // HTTP 4xx/5xx: fall back to legacy floater + if (self->getNavigateResultCode() >= 400) + { + fallbackToLegacy(); + } + } + } + else if (event == LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE || + event == LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH || + event == LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED) + { + fallbackToLegacy(); + } } diff --git a/indra/newview/llfloaterbuycurrencyhtml.h b/indra/newview/llfloaterbuycurrencyhtml.h index 23a29cae4c..4b28cf6967 100644 --- a/indra/newview/llfloaterbuycurrencyhtml.h +++ b/indra/newview/llfloaterbuycurrencyhtml.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2026, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,36 +24,36 @@ * $/LicenseInfo$ */ -#ifndef LL_LLFLOATERBUYCURRENCYHTML_H -#define LL_LLFLOATERBUYCURRENCYHTML_H +#pragma once #include "llfloater.h" #include "llmediactrl.h" -class LLFloaterBuyCurrencyHTML : +class LLFloaterBuyCurrencyHTML: public LLFloater, public LLViewerMediaObserver { - public: - LLFloaterBuyCurrencyHTML( const LLSD& key ); + friend class LLFloaterReg; - /*virtual*/ bool postBuild(); - /*virtual*/ void onClose( bool app_quitting ); +public: + LLFloaterBuyCurrencyHTML(const LLSD& key); + ~LLFloaterBuyCurrencyHTML(); + bool postBuild() override; + void onClose(bool app_quitting) override; + void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; - // inherited from LLViewerMediaObserver - /*virtual*/ void handleMediaEvent( LLPluginClassMedia* self, EMediaEvent event ); + void navigateToFinalURL(); + void setShortfall(S32 shortfall) { mShortfall = shortfall; } + void setFallbackContext(const std::string& message, S32 sum); + static std::string buildURL(S32 shortfall = 0); - // allow our controlling parent to tell us paramters - void setParams( bool specific_sum_requested, const std::string& message, S32 sum ); +private: + void fallbackToLegacy(); - // parse and construct URL and set browser to navigate there. - void navigateToFinalURL(); - - private: - LLMediaCtrl* mBrowser; - bool mSpecificSumRequested; - std::string mMessage; - S32 mSum; + LLMediaCtrl* mBrowser; + S32 mShortfall{0}; + bool mHasFallbackTarget{false}; + std::string mFallbackMessage; + S32 mFallbackSum{0}; }; -#endif // LL_LLFLOATERBUYCURRENCYHTML_H diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 3ac5c9d896..7897339a2d 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -211,6 +211,7 @@ #include "llsky.h" #include "llstatview.h" #include "llstatusbar.h" // sendMoneyBalanceRequest(), owns L$ balance +#include "llbuycurrencyhtml.h" #include "llsurface.h" #include "lltexturecache.h" #include "lltexturefetch.h" @@ -1991,6 +1992,7 @@ bool idle_startup() // Get L$ and ownership credit information LL_INFOS() << "Requesting Money Balance" << LL_ENDL; LLStatusBar::sendMoneyBalanceRequest(); + LLBuyCurrencyHTML::checkFeatureFlag(); do_startup_frame(); diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml index 996937cd45..782d45120b 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml @@ -1,20 +1,17 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater - can_resize="false" + can_resize="true" + can_minimize="false" can_close="true" - width="422" - height="202" + min_width="360" + min_height="400" + width="450" + height="650" layout="topleft" name="floater_buy_currency_html" - help_topic="floater_buy_currency_html" save_rect="true" single_instance="true" - title="BUY CURRENCY" -> - <floater.string - name="buy_currency_url" translate="false"> - https://quick-buy.secondlife.com/[LANGUAGE]/display/?sa=[SPECIFIC_AMOUNT]&sum=[SUM]&msg=[MSG]&bal=[BAL] - </floater.string> + title="BUY L$"> <web_browser trusted_content="true" follows="all" |
