summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt6
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl190
-rw-r--r--indra/newview/llappviewer.cpp34
-rw-r--r--indra/newview/llappviewer.h2
-rw-r--r--indra/newview/llenvironmentmap.cpp116
-rw-r--r--indra/newview/lllogininstance.cpp68
-rw-r--r--indra/newview/llpanelface.cpp141
-rw-r--r--indra/newview/llpanelface.h3
-rw-r--r--indra/newview/llreflectionmap.cpp64
-rw-r--r--indra/newview/llreflectionmap.h (renamed from indra/newview/llenvironmentmap.h)17
-rw-r--r--indra/newview/llreflectionmapmanager.cpp106
-rw-r--r--indra/newview/llreflectionmapmanager.h51
-rw-r--r--indra/newview/llsecapi.h3
-rw-r--r--indra/newview/llsechandler_basic.cpp5
-rw-r--r--indra/newview/llsechandler_basic.h3
-rw-r--r--indra/newview/llstartup.cpp45
-rw-r--r--indra/newview/llviewerwindow.cpp147
-rw-r--r--indra/newview/llviewerwindow.h12
-rw-r--r--indra/newview/pipeline.cpp87
-rw-r--r--indra/newview/pipeline.h7
-rw-r--r--indra/newview/skins/default/xui/en/floater_mfa.xml49
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml21
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml4
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp13
-rw-r--r--indra/newview/tests/llsecapi_test.cpp1
27 files changed, 980 insertions, 228 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 978c76285a..e7aa884f6b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -197,7 +197,6 @@ set(viewer_SOURCE_FILES
lldynamictexture.cpp
llemote.cpp
llenvironment.cpp
- llenvironmentmap.cpp
llestateinfomodel.cpp
lleventnotifier.cpp
lleventpoll.cpp
@@ -547,6 +546,8 @@ set(viewer_SOURCE_FILES
llproductinforequest.cpp
llprogressview.cpp
llrecentpeople.cpp
+ llreflectionmap.cpp
+ llreflectionmapmanager.cpp
llregioninfomodel.cpp
llregionposition.cpp
llremoteparcelrequest.cpp
@@ -835,7 +836,6 @@ set(viewer_HEADER_FILES
lldynamictexture.h
llemote.h
llenvironment.h
- llenvironmentmap.h
llestateinfomodel.h
lleventnotifier.h
lleventpoll.h
@@ -1173,6 +1173,8 @@ set(viewer_HEADER_FILES
llproductinforequest.h
llprogressview.h
llrecentpeople.h
+ llreflectionmap.h
+ llreflectionmapmanager.h
llregioninfomodel.h
llregionposition.h
llremoteparcelrequest.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 826f5ce030..09a7391e4e 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.0
+6.6.1
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a6dce3cceb..20b708fe99 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16829,5 +16829,16 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>MFAHash</key>
+ <map>
+ <key>Comment</key>
+ <string>Override MFA state hash for authentication</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string></string>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 6958841d05..5bb64e18a7 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -28,6 +28,8 @@
/*[EXTRA_CODE_HERE]*/
+#define REFMAP_COUNT 8
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -40,9 +42,13 @@ uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
-uniform samplerCube reflectionMap;
+uniform samplerCube reflectionMap[REFMAP_COUNT];
uniform sampler2D lightFunc;
+uniform int refmapCount;
+
+uniform vec3 refOrigin[REFMAP_COUNT];
+
uniform float blur_size;
uniform float blur_fidelity;
@@ -74,8 +80,136 @@ vec3 srgb_to_linear(vec3 c);
vec4 applyWaterFogView(vec3 pos, vec4 color);
#endif
+
+
+// from https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
+
+// original reference implementation:
+/*
+bool intersect(const Ray &ray) const
+{
+ float t0, t1; // solutions for t if the ray intersects
+#if 0
+ // geometric solution
+ Vec3f L = center - orig;
+ float tca = L.dotProduct(dir);
+ // if (tca < 0) return false;
+ float d2 = L.dotProduct(L) - tca * tca;
+ if (d2 > radius2) return false;
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+#else
+ // analytic solution
+ Vec3f L = orig - center;
+ float a = dir.dotProduct(dir);
+ float b = 2 * dir.dotProduct(L);
+ float c = L.dotProduct(L) - radius2;
+ if (!solveQuadratic(a, b, c, t0, t1)) return false;
+#endif
+ if (t0 > t1) std::swap(t0, t1);
+
+ if (t0 < 0) {
+ t0 = t1; // if t0 is negative, let's use t1 instead
+ if (t0 < 0) return false; // both t0 and t1 are negative
+ }
+
+ t = t0;
+
+ return true;
+} */
+
+// adapted -- assume that origin is inside sphere, return distance from origin to edge of sphere
+float sphereIntersect(vec3 origin, vec3 dir, vec4 sph )
+{
+ float t0, t1; // solutions for t if the ray intersects
+
+ vec3 center = sph.xyz;
+ float radius2 = sph.w * sph.w;
+
+ vec3 L = center - origin;
+ float tca = dot(L,dir);
+
+ float d2 = dot(L,L) - tca * tca;
+
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+
+ return t1;
+}
+
+vec3 sampleRefMap(vec3 pos, vec3 dir, float lod)
+{
+ float wsum = 0.0;
+
+ vec3 col = vec3(0,0,0);
+
+ for (int i = 0; i < refmapCount; ++i)
+ //int i = 0;
+ {
+ float r = 16.0;
+ vec3 delta = pos.xyz-refOrigin[i].xyz;
+ if (length(delta) < r)
+ {
+ float w = 1.0/max(dot(delta, delta), r);
+ w *= w;
+ w *= w;
+
+ // parallax adjustment
+ float d = sphereIntersect(pos, dir, vec4(refOrigin[i].xyz, r));
+
+ {
+ vec3 v = pos + dir * d;
+ v -= refOrigin[i].xyz;
+ v = env_mat * v;
+
+ float min_lod = textureQueryLod(reflectionMap[i],v).y; // lower is higher res
+ col += textureLod(reflectionMap[i], v, max(min_lod, lod)).rgb*w;
+ wsum += w;
+ }
+ }
+ }
+
+ if (wsum > 0.0)
+ {
+ col *= 1.0/wsum;
+ }
+ else
+ {
+ // this pixel not covered by a probe, fallback to "full scene" environment map
+ vec3 v = env_mat * dir;
+ float min_lod = textureQueryLod(environmentMap, v).y; // lower is higher res
+ col = textureLod(environmentMap, v, max(min_lod, lod)).rgb;
+ }
+
+ return col;
+}
+
+vec3 sampleAmbient(vec3 pos, vec3 dir, float lod)
+{
+ vec3 col = sampleRefMap(pos, dir, lod);
+
+ //desaturate
+ vec3 hcol = col *0.5;
+
+ col *= 2.0;
+ col = vec3(
+ col.r + hcol.g + hcol.b,
+ col.g + hcol.r + hcol.b,
+ col.b + hcol.r + hcol.g
+ );
+
+ col *= 0.333333;
+
+ return col*0.6; // fudge darker
+
+}
+
void main()
{
+ float reflection_lods = 11; // TODO -- base this on resolution of reflection map instead of hard coding
+
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec4 pos = getPositionWithDepth(tc, depth);
@@ -106,25 +240,29 @@ void main()
vec3 atten;
calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
+ //vec3 amb_vec = env_mat * norm.xyz;
+
+ vec3 ambenv = sampleAmbient(pos.xyz, norm.xyz, reflection_lods-1);
+ amblit = mix(ambenv, amblit, amblit);
color.rgb = amblit;
+
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
- color.rgb *= ambient;
+ //float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ //ambient *= 0.5;
+ //ambient *= ambient;
+ //ambient = (1.0 - ambient);
+ //color.rgb *= ambient;
vec3 sun_contrib = min(da, scol) * sunlit;
color.rgb += sun_contrib;
color.rgb *= diffuse.rgb;
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
vec3 env_vec = env_mat * refnormpersp;
-
if (spec.a > 0.0) // specular reflection
{
- float sa = dot(refnormpersp, light_dir.xyz);
+ float sa = dot(normalize(refnormpersp), light_dir.xyz);
vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
@@ -133,28 +271,30 @@ void main()
color.rgb += spec_contrib;
// add reflection map - EXPERIMENTAL WORK IN PROGRESS
- float reflection_lods = 11; // TODO -- base this on resolution of reflection map instead of hard coding
- float min_lod = textureQueryLod(reflectionMap,env_vec).y; // lower is higher res
-
- //vec3 reflected_color = texture(reflectionMap, env_vec, (1.0-spec.a)*reflection_lod).rgb;
- vec3 reflected_color = textureLod(reflectionMap, env_vec, max(min_lod, (1.0-spec.a)*reflection_lods)).rgb;
- //vec3 reflected_color = texture(reflectionMap, env_vec).rgb;
- //vec3 reflected_color = normalize(env_vec)*0.5+0.5;
- reflected_color *= spec.rgb;
+
+ float lod = (1.0-spec.a)*reflection_lods;
+ vec3 reflected_color = sampleRefMap(pos.xyz, normalize(refnormpersp), lod);
+ reflected_color *= 0.5; // fudge darker, not sure where there's a multiply by two and it's late
+ float fresnel = 1.0+dot(normalize(pos.xyz), norm.xyz);
+ fresnel += spec.a;
+ fresnel *= fresnel;
+ //fresnel *= spec.a;
+ reflected_color *= spec.rgb*min(fresnel, 1.0);
+ //reflected_color = srgb_to_linear(reflected_color);
vec3 mixer = clamp(color.rgb + vec3(1,1,1) - spec.rgb, vec3(0,0,0), vec3(1,1,1));
-
- color.rgb = mix(reflected_color*sqrt(spec.a*0.8), color, mixer);
-
- //color.rgb = mix(reflected_color * spec.rgb * sqrt(spec.a*0.8), color.rgb, color.rgb);
- //color.rgb += reflected_color * spec.rgb; // * sqrt(spec.a*0.8), color.rgb, color.rgb);
+ color.rgb = mix(reflected_color, color, mixer);
}
color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
if (envIntensity > 0.0)
{ // add environmentmap
- vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
- color = mix(color.rgb, reflected_color, envIntensity);
+ vec3 reflected_color = sampleRefMap(pos.xyz, normalize(refnormpersp), 0.0);
+ float fresnel = 1.0+dot(normalize(pos.xyz), norm.xyz);
+ fresnel *= fresnel;
+ fresnel = fresnel * 0.95 + 0.05;
+ reflected_color *= fresnel;
+ color = mix(color.rgb, reflected_color, envIntensity);
}
if (norm.w < 0.5)
@@ -172,6 +312,4 @@ void main()
// convert to linear as fullscreen lights need to sum in linear colorspace
// and will be gamma (re)corrected downstream...
frag_color.rgb = srgb_to_linear(color.rgb);
- //frag_color.r = 1.0;
- frag_color.a = bloom;
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index a63203f3cb..cb2e6afcc0 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1512,22 +1512,23 @@ bool LLAppViewer::doFrame()
// Render scene.
// *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
- if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Display" )
- pingMainloopTimeout("Main:Display");
- gGLActive = TRUE;
+ if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Display");
+ pingMainloopTimeout("Main:Display");
+ gGLActive = TRUE;
- display();
+ display();
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
- pingMainloopTimeout("Main:Snapshot");
- LLFloaterSnapshot::update(); // take snapshots
- LLFloaterOutfitSnapshot::update();
- gGLActive = FALSE;
- }
- }
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot");
+ pingMainloopTimeout("Main:Snapshot");
+ gPipeline.mReflectionMapManager.update();
+ LLFloaterSnapshot::update(); // take snapshots
+ LLFloaterOutfitSnapshot::update();
+ gGLActive = FALSE;
+ }
+ }
}
{
@@ -3138,6 +3139,11 @@ bool LLAppViewer::initWindow()
return true;
}
+bool LLAppViewer::isUpdaterMissing()
+{
+ return mUpdaterNotFound;
+}
+
void LLAppViewer::writeDebugInfo(bool isStatic)
{
#if LL_WINDOWS && LL_BUGSPLAT
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index a86fa7d873..68c04d450b 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -105,7 +105,7 @@ public:
bool quitRequested() { return mQuitRequested; }
bool logoutRequestSent() { return mLogoutRequestSent; }
bool isSecondInstance() { return mSecondInstance; }
- bool isUpdaterMissing() { return mUpdaterNotFound; }
+ bool isUpdaterMissing(); // In use by tests
void writeDebugInfo(bool isStatic=true);
diff --git a/indra/newview/llenvironmentmap.cpp b/indra/newview/llenvironmentmap.cpp
deleted file mode 100644
index ee185d8ce7..0000000000
--- a/indra/newview/llenvironmentmap.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * @file llenvironmentmap.cpp
- * @brief LLEnvironmentMap class implementation
- *
- * $LicenseInfo:firstyear=2022&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2022, 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
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llenvironmentmap.h"
-#include "pipeline.h"
-#include "llviewerwindow.h"
-
-LLEnvironmentMap::LLEnvironmentMap()
-{
- mOrigin.setVec(0, 0, 0);
-}
-
-void LLEnvironmentMap::update(const LLVector3& origin, U32 resolution)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
-
- mOrigin = origin;
-
- // allocate images
- std::vector<LLPointer<LLImageRaw> > rawimages;
- rawimages.reserve(6);
-
- for (int i = 0; i < 6; ++i)
- {
- rawimages.push_back(new LLImageRaw(resolution, resolution, 3));
- }
-
- // ============== modified copy/paste of LLFloater360Capture::capture360Images() follows ==============
-
- // these are the 6 directions we will point the camera, see LLCubeMap::mTargets
- LLVector3 look_dirs[6] = {
- LLVector3(-1, 0, 0),
- LLVector3(1, 0, 0),
- LLVector3(0, -1, 0),
- LLVector3(0, 1, 0),
- LLVector3(0, 0, -1),
- LLVector3(0, 0, 1)
- };
-
- LLVector3 look_upvecs[6] = {
- LLVector3(0, -1, 0),
- LLVector3(0, -1, 0),
- LLVector3(0, 0, -1),
- LLVector3(0, 0, 1),
- LLVector3(0, -1, 0),
- LLVector3(0, -1, 0)
- };
-
- // save current view/camera settings so we can restore them afterwards
- S32 old_occlusion = LLPipeline::sUseOcclusion;
-
- // set new parameters specific to the 360 requirements
- LLPipeline::sUseOcclusion = 0;
- LLViewerCamera* camera = LLViewerCamera::getInstance();
- LLVector3 old_origin = camera->getOrigin();
- F32 old_fov = camera->getView();
- F32 old_aspect = camera->getAspect();
- F32 old_yaw = camera->getYaw();
-
- // camera constants for the square, cube map capture image
- camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV
- camera->setView(F_PI_BY_TWO);
- camera->yaw(0.0);
- camera->setOrigin(mOrigin);
-
- // for each of the 6 directions we shoot...
- for (int i = 0; i < 6; i++)
- {
- // set up camera to look in each direction
- camera->lookDir(look_dirs[i], look_upvecs[i]);
-
- // call the (very) simplified snapshot code that simply deals
- // with a single image, no sub-images etc. but is very fast
- gViewerWindow->simpleSnapshot(rawimages[i],
- resolution, resolution, 1);
- }
-
- // restore original view/camera/avatar settings settings
- camera->setAspect(old_aspect);
- camera->setView(old_fov);
- camera->yaw(old_yaw);
- camera->setOrigin(old_origin);
-
- LLPipeline::sUseOcclusion = old_occlusion;
-
- // ====================================================
-
- mCubeMap = new LLCubeMap(false);
- mCubeMap->initEnvironmentMap(rawimages);
-}
-
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 531f0b172d..a3d0eb5796 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -61,6 +61,7 @@
#include "lltrans.h"
#include <boost/scoped_ptr.hpp>
+#include <boost/regex.hpp>
#include <sstream>
const S32 LOGIN_MAX_RETRIES = 0; // Viewer should not autmatically retry login
@@ -224,8 +225,9 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
request_params["id0"] = mSerialNumber;
request_params["host_id"] = gSavedSettings.getString("HostID");
request_params["extended_errors"] = true; // request message_id and message_args
+ request_params["token"] = "";
- // log request_params _before_ adding the credentials
+ // log request_params _before_ adding the credentials or sensitive MFA hash data
LL_DEBUGS("LLLogin") << "Login parameters: " << LLSDOStreamer<LLSDNotationFormatter>(request_params) << LL_ENDL;
// Copy the credentials into the request after logging the rest
@@ -238,6 +240,33 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
request_params[it->first] = it->second;
}
+ std::string mfa_hash = gSavedSettings.getString("MFAHash"); //non-persistent to enable testing
+ std::string grid(LLGridManager::getInstance()->getGridId());
+ std::string user_id = user_credential->userID();
+ if (gSecAPIHandler)
+ {
+ if (mfa_hash.empty())
+ {
+ // normal execution, mfa_hash was not set from debug setting so load from protected store
+ LLSD data_map = gSecAPIHandler->getProtectedData("mfa_hash", grid);
+ if (data_map.isMap() && data_map.has(user_id))
+ {
+ mfa_hash = data_map[user_id].asString();
+ }
+ }
+ else
+ {
+ // SL-16888 the mfa_hash is being overridden for testing so save it for consistency for future login requests
+ gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, mfa_hash);
+ }
+ }
+ else
+ {
+ LL_WARNS() << "unable to access protected store for mfa_hash" << LL_ENDL;
+ }
+
+ request_params["mfa_hash"] = mfa_hash;
+
// Specify desired timeout/retry options
LLSD http_params;
F32 srv_timeout = llclamp(gSavedSettings.getF32("LoginSRVTimeout"), LOGIN_SRV_TIMEOUT_MIN, LOGIN_SRV_TIMEOUT_MAX);
@@ -250,6 +279,11 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
mRequestData["params"] = request_params;
mRequestData["options"] = requested_options;
mRequestData["http_params"] = http_params;
+#if LL_RELEASE_FOR_DOWNLOAD
+ mRequestData["wait_for_updater"] = !gSavedSettings.getBOOL("CmdLineSkipUpdater") && !LLAppViewer::instance()->isUpdaterMissing();
+#else
+ mRequestData["wait_for_updater"] = false;
+#endif
}
bool LLLoginInstance::handleLoginEvent(const LLSD& event)
@@ -406,6 +440,38 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
boost::bind(&LLLoginInstance::syncWithUpdater, this, resp, _1, _2));
}
}
+ else if(reason_response == "mfa_challenge")
+ {
+ LL_DEBUGS("LLLogin") << " MFA challenge" << LL_ENDL;
+
+ if (gViewerWindow)
+ {
+ gViewerWindow->setShowProgress(FALSE);
+ }
+
+ LLSD args(llsd::map( "MESSAGE", LLTrans::getString(response["message_id"]) ));
+ LLSD payload;
+ LLNotificationsUtil::add("PromptMFAToken", args, payload, [=](LLSD const & notif, LLSD const & response) {
+ bool continue_clicked = response["continue"].asBoolean();
+ std::string token = response["token"].asString();
+ LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL;
+
+ // strip out whitespace - SL-17034/BUG-231938
+ token = boost::regex_replace(token, boost::regex("\\s"), "");
+
+ if (continue_clicked && !token.empty())
+ {
+ LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL;
+
+ // Set the request data to true and retry login.
+ mRequestData["params"]["token"] = token;
+ reconnect();
+ } else {
+ LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL;
+ attemptComplete();
+ }
+ });
+ }
else if( reason_response == "key"
|| reason_response == "presence"
|| reason_response == "connect"
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 6b3ca43402..de59490eea 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -2319,7 +2319,11 @@ void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata)
void LLPanelFace::onCommitMaterialID(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = static_cast<LLPanelFace*>(userdata);
- LLSelectedTEMaterial::setMaterialID(self, self->getCurrentMaterialID());
+ LLUUID matID = self->getCurrentMaterialID();
+ LLSelectedTEMaterial::setMaterialID(self, matID);
+
+ // Temporary demo hack - replace the TE entries with those from the Material's LLSD
+ applyMaterialUUID(matID, userdata);
}
// static
@@ -2564,27 +2568,26 @@ void LLPanelFace::onAlignTexture(void* userdata)
#include "llviewerassetupload.h"
#include "llviewermenufile.h"
#include "llsd.h"
-#pragma warning (disable: 4189)
void LLPanelFace::onSaveMaterial(void* userdata)
{
// DRTVWR-559, Q&D material picker - save to inventory goes here
- LL_DEBUGS("Material") << "saving material to inventory" << LL_ENDL;
-
- LLPanelFace* self = (LLPanelFace*)userdata;
+ LL_DEBUGS("Material") << "saving render material to inventory" << LL_ENDL;
std::string name = "New Material";
- LLSD* mat_llsd = new LLSD("Surely you jest...");
- // TBD populate mat_llsd with material data
- self->onCloseTexturePicker(*mat_llsd); // certainly wrong, but something like this?
-
// gen a new uuid for this asset
LLTransactionID tid;
- tid.generate();
+ tid.generate(); // timestamp-based randomization + uniquification
LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
- LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_MATERIAL, LLFileSystem::WRITE);
- fmt_file.write(mat_llsd->asBinary().data(), mat_llsd->size());
+ // populate mat_llsd with material data
+ LLSD* mat_llsd = new LLSD();
+ renderMaterialToLLSD(mat_llsd, new_asset_id, userdata);
+
+ LLFileSystem material_file(new_asset_id, LLAssetType::AT_MATERIAL, LLFileSystem::WRITE);
+ material_file.write(mat_llsd->asBinary().data(), mat_llsd->size());
+
+ delete(mat_llsd);
S32 expected_upload_cost = 0;// LLAgentBenefitsMgr::current().getTextureUploadCost();
@@ -2612,6 +2615,120 @@ void LLPanelFace::onSaveMaterial(void* userdata)
upload_new_resource(p_upload_info);
}
+// Fill an LLSD with data describing the current face's texture settings
+// TODO 2022-05 FUBAR there are both colliding and different data in LLPanelFace vs the TE. Also, neither one has the diffuse tex settings.
+//
+void LLPanelFace::renderMaterialToLLSD(LLSD* sd, LLUUID uuid, void* userdata)
+{
+ llassert(userdata != nullptr);
+
+ sd->insert("RenderMaterialUUID", LLSD(uuid));
+
+ /* pf stuff is probably useless
+ // pull data from the LLPanelFace
+ LLPanelFace* instance = static_cast<LLPanelFace*>(userdata);
+ sd->insert("pfNormalMap", LLSD(instance->getCurrentNormalMap()));
+ sd->insert("pfSpecularMap", LLSD(instance->getCurrentSpecularMap()));
+ sd->insert("pfShininess", LLSD(static_cast<S32>(instance->getCurrentShininess())));
+ sd->insert("pfBumpiness", LLSD(static_cast<S32>(instance->getCurrentBumpiness())));
+ sd->insert("pfAlphaMode", LLSD(static_cast<S32>(instance->getCurrentDiffuseAlphaMode())));
+ sd->insert("pfAlphaCutoff", LLSD(static_cast<S32>(instance->getCurrentAlphaMaskCutoff())));
+ sd->insert("pfEnvIntensity", LLSD(static_cast<S32>(instance->getCurrentEnvIntensity())));
+ sd->insert("pfGlossiness", LLSD(static_cast<S32>(instance->getCurrentGlossiness())));
+ sd->insert("pfNormalRotation", LLSD(instance->getCurrentBumpyRot()));
+ sd->insert("pfNormalScaleU", LLSD(instance->getCurrentBumpyScaleU()));
+ sd->insert("pfNormalScaleV", LLSD(instance->getCurrentBumpyScaleV()));
+ sd->insert("pfNormalOffsetU", LLSD(instance->getCurrentBumpyOffsetU()));
+ sd->insert("pfNormalOffsetV", LLSD(instance->getCurrentBumpyOffsetV()));
+ sd->insert("pfSpecularRotation", LLSD(instance->getCurrentShinyRot()));
+ sd->insert("pfSpecularScaleU", LLSD(instance->getCurrentShinyScaleU()));
+ sd->insert("pfSpecularScaleV", LLSD(instance->getCurrentShinyScaleV()));
+ sd->insert("pfSpecularOffsetU", LLSD(instance->getCurrentShinyOffsetU()));
+ sd->insert("pfSpecularOffsetV", LLSD(instance->getCurrentShinyOffsetV()));
+ sd->insert("pfMaterialID", LLSD(instance->getCurrentMaterialID()));
+ */
+
+ // now pull same data from the selected TE (same but different. W T F?)
+ LLMaterialPtr mat = nullptr;
+ bool ident; // ?
+ LLSelectedTEMaterial::getCurrent(mat, ident);
+
+ sd->insert("teMaterialID", LLSD(mat->getMaterialID()));
+
+ sd->insert("teNormalMap", LLSD(mat->getNormalID()));
+ sd->insert("teNormalOffsetX", LLSD(mat->getNormalOffsetX()));
+ sd->insert("teNormalOffsetY", LLSD(mat->getNormalOffsetY()));
+ sd->insert("teNormalRepeatX", LLSD(mat->getNormalRepeatX()));
+ sd->insert("teNormalRepeatY", LLSD(mat->getNormalRepeatY()));
+ sd->insert("teNormalRotation", LLSD(mat->getNormalRotation()));
+
+ sd->insert("teSpecularMap", LLSD(mat->getSpecularID()));
+ LLColor4U color = mat->getSpecularLightColor();
+ sd->insert("teSpecularColorR", LLSD(static_cast<S32>(color.mV[0])));
+ sd->insert("teSpecularColorG", LLSD(static_cast<S32>(color.mV[1])));
+ sd->insert("teSpecularColorB", LLSD(static_cast<S32>(color.mV[2])));
+ sd->insert("teSpecularColorA", LLSD(static_cast<S32>(color.mV[3])));
+ sd->insert("teSpecularExponent", LLSD(static_cast<S32>(mat->getSpecularLightExponent())));
+ sd->insert("teSpecularOffsetX", LLSD(mat->getSpecularOffsetX()));
+ sd->insert("teSpecularOffsetY", LLSD(mat->getSpecularOffsetY()));
+ sd->insert("teSpecularRepeatX", LLSD(mat->getSpecularRepeatX()));
+ sd->insert("teSpecularRepeatY", LLSD(mat->getSpecularRepeatY()));
+ sd->insert("teSpecularRotation", LLSD(mat->getSpecularRotation()));
+
+ sd->insert("teAlphaMode", LLSD(static_cast<S32>(mat->getDiffuseAlphaMode())));
+ sd->insert("teAlphaCutoff", LLSD(static_cast<S32>(mat->getAlphaMaskCutoff())));
+ sd->insert("teEnvIntensity", LLSD(static_cast<S32>(mat->getEnvironmentIntensity())));
+ sd->insert("teShaderMask", LLSD(static_cast<S32>(mat->getShaderMask())));
+}
+
+// Take the individual texture settings from the material and apply to current face & TE
+void LLPanelFace::applyMaterialUUID(LLUUID uuid, void* userdata)
+{
+ llassert(userdata != nullptr);
+ //LLPanelFace* instance = static_cast<LLPanelFace*>(userdata);
+
+ LLFileSystem material_file(uuid, LLAssetType::AT_MATERIAL, LLFileSystem::READ);
+ S32 bufsize = material_file.getSize();
+ llassert(bufsize > 0);
+ U8* buffer = new U8(bufsize);
+ material_file.read(buffer, bufsize);
+ LLSD* matSD = (LLSD*) buffer; // static_cast complains here (?)
+
+ llassert(uuid == matSD->get("MaterialUUID").asUUID()); // if not, whoo boy
+
+ LLMaterialPtr mat = nullptr;
+ bool ident; // ?
+ LLSelectedTEMaterial::getCurrent(mat, ident);
+
+ mat->setMaterialID(matSD->get("teMaterialID").asUUID());
+
+ mat->setNormalID(matSD->get("teNormalMap").asUUID());
+ mat->setNormalOffsetX(matSD->get("teNormalOffsetX").asReal());
+ mat->setNormalOffsetY(matSD->get("teNormalOffsetY").asReal());
+ mat->setNormalRepeatX(matSD->get("teNormalRepeatX").asReal());
+ mat->setNormalRepeatY(matSD->get("teNormalRepeatY").asReal());
+ mat->setNormalRotation(matSD->get("teNormalRotation").asReal());
+
+ mat->setSpecularID(matSD->get("teSpecularMap").asUUID());
+ LLColor4U color;
+ color.mV[0] = static_cast<U8>(matSD->get("teSecularColorR").asInteger());
+ color.mV[1] = static_cast<U8>(matSD->get("teSecularColorG").asInteger());
+ color.mV[2] = static_cast<U8>(matSD->get("teSecularColorB").asInteger());
+ color.mV[3] = static_cast<U8>(matSD->get("teSecularColorA").asInteger());
+ mat->setSpecularLightColor(color);
+ mat->setSpecularLightExponent(static_cast<U8>(matSD->get("teSpecularExponent").asInteger()));
+ mat->setSpecularOffsetX(matSD->get("teSpecularOffsetX").asReal());
+ mat->setSpecularOffsetY(matSD->get("teSpecularOffsetY").asReal());
+ mat->setSpecularRepeatX(matSD->get("teSpecularRepeatX").asReal());
+ mat->setSpecularRepeatY(matSD->get("teSpecularRepeatY").asReal());
+ mat->setSpecularRotation(matSD->get("teSpecularRotation").asReal());
+
+ mat->setDiffuseAlphaMode(static_cast<U8>(matSD->get("teAlphaMode").asInteger()));
+ mat->setAlphaMaskCutoff(static_cast<U8>(matSD->get("teAlphaCutoff").asInteger()));
+ mat->setEnvironmentIntensity(static_cast<U8>(matSD->get("teEnvIntensity").asInteger()));
+ //mat->setShaderMask(static_cast<U32>(matSD->get(teShaderMask").asInteger());
+}
+
// TODO: I don't know who put these in or what these are for???
void LLPanelFace::setMediaURL(const std::string& url)
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 9282b70b3c..2a53b7ff15 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -205,7 +205,10 @@ protected:
static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
static void onClickAutoFix(void*);
static void onAlignTexture(void*);
+
static void onSaveMaterial(void*);
+ static void renderMaterialToLLSD(LLSD* sd, LLUUID uuid, void* userdata);
+ static void applyMaterialUUID(LLUUID uuid, void*);
static F32 valueGlow(LLViewerObject* object, S32 face);
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
new file mode 100644
index 0000000000..b75dba877e
--- /dev/null
+++ b/indra/newview/llreflectionmap.cpp
@@ -0,0 +1,64 @@
+/**
+ * @file llreflectionmap.cpp
+ * @brief LLReflectionMap class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llreflectionmap.h"
+#include "pipeline.h"
+#include "llviewerwindow.h"
+
+LLReflectionMap::LLReflectionMap()
+{
+}
+
+void LLReflectionMap::update(const LLVector3& origin, U32 resolution)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(LLPipeline::sRenderDeferred);
+
+ // make sure resolution is < gPipeline.mDeferredScreen.getWidth()
+
+ while (resolution > gPipeline.mDeferredScreen.getWidth() ||
+ resolution > gPipeline.mDeferredScreen.getHeight())
+ {
+ resolution /= 2;
+ }
+
+ if (resolution == 0)
+ {
+ return;
+ }
+
+ mOrigin.load3(origin.mV);
+
+ mCubeMap = new LLCubeMap(false);
+ mCubeMap->initReflectionMap(resolution);
+
+ gViewerWindow->cubeSnapshot(origin, mCubeMap);
+
+ mCubeMap->generateMipMaps();
+}
+
diff --git a/indra/newview/llenvironmentmap.h b/indra/newview/llreflectionmap.h
index 7d951eb678..7d39e7e562 100644
--- a/indra/newview/llenvironmentmap.h
+++ b/indra/newview/llreflectionmap.h
@@ -1,6 +1,6 @@
/**
- * @file llenvironmentmap.h
- * @brief LLEnvironmentMap class declaration
+ * @file llreflectionmap.h
+ * @brief LLReflectionMap class declaration
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -28,21 +28,24 @@
#include "llcubemap.h"
-class LLEnvironmentMap
+class LLReflectionMap : public LLRefCount
{
public:
// allocate an environment map of the given resolution
- LLEnvironmentMap();
+ LLReflectionMap();
// update this environment map
// origin - position in agent space to generate environment map from in agent space
// resolution - size of cube map to generate
void update(const LLVector3& origin, U32 resolution);
+ // point at which environment map was generated from (in agent space)
+ LLVector4a mOrigin;
+
+ // distance from viewer camera
+ F32 mDistance;
+
// cube map used to sample this environment map
LLPointer<LLCubeMap> mCubeMap;
-
- // point at which environment map was generated from (in agent space)
- LLVector3 mOrigin;
};
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
new file mode 100644
index 0000000000..95b72e1d3b
--- /dev/null
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -0,0 +1,106 @@
+/**
+ * @file llreflectionmapmanager.cpp
+ * @brief LLReflectionMapManager class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llreflectionmapmanager.h"
+#include "llviewercamera.h"
+
+LLReflectionMapManager::LLReflectionMapManager()
+{
+
+}
+
+struct CompareReflectionMapDistance
+{
+
+};
+
+
+struct CompareProbeDistance
+{
+ bool operator()(const LLReflectionMap& lhs, const LLReflectionMap& rhs)
+ {
+ return lhs.mDistance < rhs.mDistance;
+ }
+};
+
+// helper class to seed octree with probes
+void LLReflectionMapManager::update()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ // naively drop probes every 16m as we move the camera around for now
+ // later, use LLSpatialPartition to manage probes
+ const F32 PROBE_SPACING = 16.f;
+ const U32 MAX_PROBES = 8;
+
+ LLVector4a camera_pos;
+ camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
+
+ for (auto& probe : mProbes)
+ {
+ LLVector4a d;
+ d.setSub(camera_pos, probe.mOrigin);
+ probe.mDistance = d.getLength3().getF32();
+ }
+
+ if (mProbes.empty() || mProbes[0].mDistance > PROBE_SPACING)
+ {
+ addProbe(LLViewerCamera::instance().getOrigin());
+ }
+
+ // update distance to camera for all probes
+ std::sort(mProbes.begin(), mProbes.end(), CompareProbeDistance());
+
+ if (mProbes.size() > MAX_PROBES)
+ {
+ mProbes.resize(MAX_PROBES);
+ }
+}
+
+void LLReflectionMapManager::addProbe(const LLVector3& pos)
+{
+ LLReflectionMap probe;
+ probe.update(pos, 1024);
+ mProbes.push_back(probe);
+}
+
+void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& maps)
+{
+ // just null out for now
+ U32 i = 0;
+ for (i = 0; i < maps.size() && i < mProbes.size(); ++i)
+ {
+ maps[i] = &(mProbes[i]);
+ }
+
+ for (++i; i < maps.size(); ++i)
+ {
+ maps[i] = nullptr;
+ }
+}
+
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
new file mode 100644
index 0000000000..40e925d916
--- /dev/null
+++ b/indra/newview/llreflectionmapmanager.h
@@ -0,0 +1,51 @@
+/**
+ * @file llreflectionmapmanager.h
+ * @brief LLReflectionMapManager class declaration
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llreflectionmap.h"
+
+class LLReflectionMapManager
+{
+public:
+ // allocate an environment map of the given resolution
+ LLReflectionMapManager();
+
+ // maintain reflection probes
+ void update();
+
+ // drop a reflection probe at the specified position in agent space
+ void addProbe(const LLVector3& pos);
+
+ // Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size()
+ // If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr.
+ // maps -- presized array of Reflection Map pointers
+ void getReflectionMaps(std::vector<LLReflectionMap*>& maps);
+
+ // list of active reflection maps
+ std::vector<LLReflectionMap> mProbes;
+};
+
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index e1320375ab..d8831fee93 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -485,6 +485,9 @@ public:
const std::string& data_id,
const std::string& map_elem)=0;
+ // ensure protected store's map is written to storage
+ virtual void syncProtectedMap() = 0;
+
public:
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 6b06abaf99..d0da3387ec 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -1608,6 +1608,11 @@ void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type,
}
}
+void LLSecAPIBasicHandler::syncProtectedMap()
+{
+ // TODO - consider unifing these functions
+ _writeProtectedData();
+}
//
// Create a credential object from an identifier and authenticator. credentials are
// per grid.
diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h
index 17e9f72f07..bd1a8f640c 100644
--- a/indra/newview/llsechandler_basic.h
+++ b/indra/newview/llsechandler_basic.h
@@ -278,6 +278,9 @@ public:
const std::string& data_id,
const std::string& map_elem);
+ // ensure protected store's map is written to storage
+ virtual void syncProtectedMap();
+
// credential management routines
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 5df8cd9cb0..5c0bb36d31 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -134,6 +134,7 @@
#include "llproxy.h"
#include "llproductinforequest.h"
#include "llqueryflags.h"
+#include "llsecapi.h"
#include "llselectmgr.h"
#include "llsky.h"
#include "llstatview.h"
@@ -1116,10 +1117,10 @@ bool idle_startup()
}
else
{
- if (reason_response != "tos")
+ if (reason_response != "tos" && reason_response != "mfa_challenge")
{
- // Don't pop up a notification in the TOS case because
- // LLFloaterTOS::onCancel() already scolded the user.
+ // Don't pop up a notification in the TOS or MFA cases because
+ // the specialized floater has already scolded the user.
std::string error_code;
if(response.has("errorcode"))
{
@@ -2363,8 +2364,31 @@ void show_release_notes_if_required()
&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
&& !gSavedSettings.getBOOL("FirstLoginThisInstall"))
{
- LLSD info(LLAppViewer::instance()->getViewerInfo());
- LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
+
+#if LL_RELEASE_FOR_DOWNLOAD
+ if (!gSavedSettings.getBOOL("CmdLineSkipUpdater")
+ && !LLAppViewer::instance()->isUpdaterMissing())
+ {
+ // Instantiate a "relnotes" listener which assumes any arriving event
+ // is the release notes URL string. Since "relnotes" is an
+ // LLEventMailDrop, this listener will be invoked whether or not the
+ // URL has already been posted. If so, it will fire immediately;
+ // otherwise it will fire whenever the URL is (later) posted. Either
+ // way, it will display the release notes as soon as the URL becomes
+ // available.
+ LLEventPumps::instance().obtain("relnotes").listen(
+ "showrelnotes",
+ [](const LLSD& url) {
+ LLWeb::loadURLInternal(url.asString());
+ return false;
+ });
+ }
+ else
+#endif // LL_RELEASE_FOR_DOWNLOAD
+ {
+ LLSD info(LLAppViewer::instance()->getViewerInfo());
+ LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
+ }
release_notes_shown = true;
}
}
@@ -3654,6 +3678,17 @@ bool process_login_success_response()
LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token);
}
+
+ // Only save mfa_hash for future logins if the user wants their info remembered.
+ if(response.has("mfa_hash") && gSavedSettings.getBOOL("RememberUser") && gSavedSettings.getBOOL("RememberPassword"))
+ {
+ std::string grid(LLGridManager::getInstance()->getGridId());
+ std::string user_id(gUserCredential->userID());
+ gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]);
+ // TODO(brad) - related to SL-17223 consider building a better interface that sync's automatically
+ gSecAPIHandler->syncProtectedMap();
+ }
+
bool success = false;
// JC: gesture loading done below, when we have an asset system
// in place. Don't delete/clear gUserCredentials until then.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 42e21f7130..f562a9458b 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -5170,6 +5170,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
gDisplaySwapBuffers = FALSE;
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -5266,6 +5267,152 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
return true;
}
+BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMap* cubemap)
+{
+ // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
+ llassert(LLPipeline::sRenderDeferred);
+
+ U32 res = cubemap->getResolution();
+
+ llassert(res <= gPipeline.mDeferredScreen.getWidth());
+ llassert(res <= gPipeline.mDeferredScreen.getHeight());
+
+
+
+ // save current view/camera settings so we can restore them afterwards
+ S32 old_occlusion = LLPipeline::sUseOcclusion;
+
+ // set new parameters specific to the 360 requirements
+ LLPipeline::sUseOcclusion = 0;
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ LLVector3 old_origin = camera->getOrigin();
+ F32 old_fov = camera->getView();
+ F32 old_aspect = camera->getAspect();
+ F32 old_yaw = camera->getYaw();
+
+ // camera constants for the square, cube map capture image
+ camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV
+ camera->setView(F_PI_BY_TWO);
+ camera->yaw(0.0);
+ camera->setOrigin(origin);
+
+ gDisplaySwapBuffers = FALSE;
+
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
+ if (prev_draw_ui != false)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+
+ LLPipeline::sShowHUDAttachments = FALSE;
+ LLRect window_rect = getWorldViewRectRaw();
+
+ LLRenderTarget scratch_space; // TODO: hold onto "scratch space" render target and allocate oncer per session (allocate takes > 1ms)
+ U32 color_fmt = GL_RGBA;
+ const bool use_depth_buffer = true;
+ const bool use_stencil_buffer = true;
+ if (scratch_space.allocate(res, res, color_fmt, use_depth_buffer, use_stencil_buffer))
+ {
+ mWorldViewRectRaw.set(0, res, res, 0);
+ scratch_space.bindTarget();
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ // "target" parameter of glCopyTexImage2D for each side of cubemap
+ U32 targets[6] = {
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
+ GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
+ };
+
+ // these are the 6 directions we will point the camera, see LLCubeMap::mTargets
+ LLVector3 look_dirs[6] = {
+ LLVector3(-1, 0, 0),
+ LLVector3(1, 0, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 1, 0),
+ LLVector3(0, 0, -1),
+ LLVector3(0, 0, 1)
+ };
+
+ LLVector3 look_upvecs[6] = {
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, -1),
+ LLVector3(0, 0, 1),
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0)
+ };
+
+ // for each of six sides of cubemap
+ for (int i = 0; i < 6; ++i)
+ {
+ // set up camera to look in each direction
+ camera->lookDir(look_dirs[i], look_upvecs[i]);
+
+ // turning this flag off here prohibits the screen swap
+ // to present the new page to the viewer - this stops
+ // the black flash in between captures when the number
+ // of render passes is more than 1. We need to also
+ // set it here because code in LLViewerDisplay resets
+ // it to TRUE each time.
+ gDisplaySwapBuffers = FALSE;
+
+ // actually render the scene
+ const U32 subfield = 0;
+ const bool do_rebuild = true;
+ const F32 zoom = 1.0;
+ const bool for_snapshot = TRUE;
+ display(do_rebuild, zoom, subfield, for_snapshot);
+
+ // copy results to cube map face
+ cubemap->enable(0);
+ cubemap->bind();
+ glCopyTexImage2D(targets[i], 0, GL_RGB, 0, 0, res, res, 0);
+ gGL.getTexUnit(0)->disable();
+ cubemap->disable();
+ }
+
+ gDisplaySwapBuffers = FALSE;
+ gDepthDirty = TRUE;
+
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ if (prev_draw_ui != false)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+ }
+
+ LLPipeline::sShowHUDAttachments = TRUE;
+
+ gPipeline.resetDrawOrders();
+ mWorldViewRectRaw = window_rect;
+ scratch_space.flush();
+ scratch_space.release();
+
+ // restore original view/camera/avatar settings settings
+ camera->setAspect(old_aspect);
+ camera->setView(old_fov);
+ camera->yaw(old_yaw);
+ camera->setOrigin(old_origin);
+
+ LLPipeline::sUseOcclusion = old_occlusion;
+
+ // ====================================================
+
+ return true;
+}
+
void LLViewerWindow::destroyWindow()
{
if (mWindow)
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 979a560508..be4e9a17a5 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -68,6 +68,7 @@ class LLWindowListener;
class LLViewerWindowListener;
class LLVOPartGroup;
class LLPopupView;
+class LLCubeMap;
#define PICK_HALF_WIDTH 5
#define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -360,6 +361,17 @@ public:
BOOL simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes);
+
+
+ // take a cubemap snapshot
+ // origin - vantage point to take the snapshot from
+ // cubemap - cubemap to store the results
+ BOOL cubeSnapshot(const LLVector3& origin, LLCubeMap* cubemap);
+
+
+ // special implementation of simpleSnapshot for reflection maps
+ BOOL reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes);
+
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
BOOL isSnapshotLocSet() const;
void resetSnapshotLoc() const;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index eaf28e9f4f..ef616f5d83 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -768,42 +768,16 @@ void LLPipeline::allocatePhysicsBuffer()
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
- refreshCachedSettings();
-
- bool save_settings = sRenderDeferred;
- if (save_settings)
- {
- // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
- gSavedSettings.setBOOL("RenderInitError", TRUE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- }
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
- if (save_settings)
- {
- // don't disable shaders on next session
- gSavedSettings.setBOOL("RenderInitError", FALSE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- }
-
- if (ret == FBO_FAILURE)
- { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
- //NOTE: if the session closes successfully after this call, deferred rendering will be
- // disabled on future sessions
- if (LLPipeline::sRenderDeferred)
- {
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- LLPipeline::refreshCachedSettings();
- }
- }
-
return ret == FBO_SUCCESS_FULLRES;
}
LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
// try to allocate screen buffers at requested resolution and samples
// - on failure, shrink number of samples and try again
// - if not multisampled, shrink resolution and try again (favor X resolution over Y)
@@ -857,8 +831,7 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
- refreshCachedSettings();
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
// remember these dimensions
mScreenWidth = resX;
mScreenHeight = resY;
@@ -962,8 +935,7 @@ inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0
bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
{
- refreshCachedSettings();
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
if (LLPipeline::sRenderDeferred)
{
S32 shadow_detail = RenderShadowDetail;
@@ -1054,6 +1026,7 @@ void LLPipeline::updateRenderDeferred()
// static
void LLPipeline::refreshCachedSettings()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
@@ -8226,12 +8199,41 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
channel = shader.enableTexture(LLShaderMgr::REFLECTION_MAP, LLTexUnit::TT_CUBE_MAP);
if (channel > -1)
{
- LLCubeMap* cube_map = mEnvironmentMap.mCubeMap;
- if (cube_map)
+ mReflectionMaps.resize(8); //TODO -- declare the number of reflection maps the shader knows about somewhere sane
+ mReflectionMapManager.getReflectionMaps(mReflectionMaps);
+ LLVector3 origin[8]; //origin of refmaps in clip space
+
+ // load modelview matrix into matrix 4a
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+ LLVector4a oa; // scratch space for transformed origin
+
+ S32 count = 0;
+ for (auto* refmap : mReflectionMaps)
+ {
+ if (refmap)
+ {
+ LLCubeMap* cubemap = refmap->mCubeMap;
+ if (cubemap)
+ {
+ cubemap->enable(channel + count);
+ cubemap->bind();
+
+ modelview.affineTransform(refmap->mOrigin, oa);
+ origin[count].set(oa.getF32ptr());
+
+ count++;
+ }
+ }
+ }
+
+ if (count > 0)
{
+ LLStaticHashedString refmapCount("refmapCount");
+ LLStaticHashedString refOrigin("refOrigin");
+ shader.uniform1i(refmapCount, count);
+ shader.uniform3fv(refOrigin, count, (F32*)origin);
setup_env_mat = true;
- cube_map->enable(channel);
- cube_map->bind();
}
}
@@ -9147,10 +9149,14 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
channel = shader.disableTexture(LLShaderMgr::REFLECTION_MAP, LLTexUnit::TT_CUBE_MAP);
if (channel > -1)
{
- LLCubeMap* cube_map = mEnvironmentMap.mCubeMap;
- if (cube_map)
+ for (int i = 0; i < mReflectionMaps.size(); ++i)
+ {
+ gGL.getTexUnit(channel + i)->disable();
+ }
+
+ if (channel == 0)
{
- cube_map->disable();
+ gGL.getTexUnit(channel)->enable(LLTexUnit::TT_TEXTURE);
}
}
@@ -11520,6 +11526,7 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
void LLPipeline::overrideEnvironmentMap()
{
- mEnvironmentMap.update(LLViewerCamera::instance().getOrigin(), 1024);
+ mReflectionMapManager.mProbes.clear();
+ mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin());
}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index c4f0c01182..975380929d 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -38,7 +38,7 @@
#include "llgl.h"
#include "lldrawable.h"
#include "llrendertarget.h"
-#include "llenvironmentmap.h"
+#include "llreflectionmapmanager.h"
#include <stack>
@@ -427,7 +427,7 @@ public:
void hideObject( const LLUUID& id );
void restoreHiddenObject( const LLUUID& id );
- LLEnvironmentMap mEnvironmentMap;
+ LLReflectionMapManager mReflectionMapManager;
void overrideEnvironmentMap();
private:
@@ -661,6 +661,9 @@ public:
//utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
LLPointer<LLVertexBuffer> mCubeVB;
+ //list of currently bound reflection maps
+ std::vector<LLReflectionMap*> mReflectionMaps;
+
//sun shadow map
LLRenderTarget mShadow[6];
LLRenderTarget mShadowOcclusion[6];
diff --git a/indra/newview/skins/default/xui/en/floater_mfa.xml b/indra/newview/skins/default/xui/en/floater_mfa.xml
new file mode 100644
index 0000000000..a649cc6d47
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_mfa.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ title="MFA Token Requred"
+ legacy_header_height="18"
+ can_minimize="false"
+ can_close="false"
+ height="110"
+ layout="topleft"
+ name="mfa_challenge"
+ help_topic="mfa_challenge"
+ width="550">
+ <text
+ type="string"
+ word_wrap="true"
+ length="1"
+ follows="top|left"
+ height="15"
+ layout="topleft"
+ left="10"
+ name="token_prompt_text"
+ top="20">
+ token prompt
+ </text>
+ <line_editor
+ follows="left|top|right"
+ height="19"
+ layout="topleft"
+ bottom_delta="40"
+ name="token_edit"
+ width="100" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Continue"
+ layout="topleft"
+ left="10"
+ name="continue_btn"
+ bottom_delta="30"
+ width="64" />
+ <button
+ follows="top|left"
+ height="20"
+ label="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel_btn"
+ bottom_delta="0"
+ width="64" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index e1f6dde6ff..4f1755a99b 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11810,4 +11810,25 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB
<tag>fail</tag>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ label="Prompt for MFA Token"
+ name="PromptMFAToken"
+ type="alertmodal">
+ [MESSAGE]
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="token" type="text" width="400" />
+ <button
+ default="true"
+ index="0"
+ name="continue"
+ text="Continue"/>
+ <button
+ index="1"
+ name="cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
</notifications>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f26ee06e6b..866196a760 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -133,6 +133,7 @@ http://secondlife.com/viewer-access-faq</string>
Please check to make sure you entered the right
* Username (like bobsmith12 or steller.sunshine)
* Password
+ * Second Factor Token (if enabled)
Also, please make sure your Caps Lock key is off.</string>
<string name="LoginFailedPasswordChanged">As a security precaution your password has been changed.
Please go to your account page at http://secondlife.com/password
@@ -192,7 +193,8 @@ Please try logging in again in a minute.</string>
Please try logging in again in a minute.</string>
<string name="LoginFailedLoggingOutSession">The system has begun logging out your last session.
Please try logging in again in a minute.</string>
-
+ <string name="LoginFailedAuthenticationMFARequired">To continue logging in, enter a new token from your multifactor authentication app.
+If you feel this is an error, please contact support@secondlife.com</string>
<!-- Disconnection -->
<string name="AgentLostConnection">This region may be experiencing trouble. Please check your connection to the Internet.</string>
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 8d1956957c..7259e66265 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -186,6 +186,15 @@ std::string LLGridManager::getAppSLURLBase(const std::string& grid_name)
{
return "myappslurl";
}
+std::string LLGridManager::getGridId(const std::string& grid)
+{
+ return std::string();
+}
+
+//LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type)
+//{
+// return nullptr;
+//}
//-----------------------------------------------------------------------------
#include "../llviewercontrol.h"
@@ -218,6 +227,7 @@ bool llHashedUniqueID(unsigned char* id)
//-----------------------------------------------------------------------------
#include "../llappviewer.h"
void LLAppViewer::forceQuit(void) {}
+bool LLAppViewer::isUpdaterMissing() { return true; }
LLAppViewer * LLAppViewer::sInstance = 0;
//-----------------------------------------------------------------------------
@@ -226,6 +236,8 @@ LLAppViewer * LLAppViewer::sInstance = 0;
static std::string gTOSType;
static LLEventPump * gTOSReplyPump = NULL;
+LLPointer<LLSecAPIHandler> gSecAPIHandler;
+
//static
LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)
{
@@ -343,6 +355,7 @@ namespace tut
gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO);
gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO);
+ gSavedSettings.declareBOOL("CmdLineSkipUpdater", TRUE, "", LLControlVariable::PERSIST_NO);
LLSD authenticator = LLSD::emptyMap();
LLSD identifier = LLSD::emptyMap();
diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp
index 37fbbb449b..7d2a9a436f 100644
--- a/indra/newview/tests/llsecapi_test.cpp
+++ b/indra/newview/tests/llsecapi_test.cpp
@@ -62,6 +62,7 @@ LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const st
void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {}
void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem, const LLSD& data) {}
void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem) {}
+void LLSecAPIBasicHandler::syncProtectedMap() {}
LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type, const std::string& data_id) { return LLSD(); }
void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type, const std::string& data_id) {}
LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid, const LLSD& identifier, const LLSD& authenticator) { return NULL; }