summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorRider Linden <rider@lindenlab.com>2017-11-17 13:04:28 -0800
committerRider Linden <rider@lindenlab.com>2017-11-17 13:04:28 -0800
commit0bf6386c61c0c28b298c2cccd82c786f754024af (patch)
tree110ff24a45be3554fb64ae9eca06fc1961cc6efc /indra/newview
parent35873f5963791af08a9951624dc96481a71fa1d7 (diff)
Now with validation.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llsettingsbase.cpp335
-rw-r--r--indra/newview/llsettingsbase.h50
-rw-r--r--indra/newview/llsettingsdaycycle.cpp90
-rw-r--r--indra/newview/llsettingsdaycycle.h4
-rw-r--r--indra/newview/llsettingssky.cpp126
-rw-r--r--indra/newview/llsettingssky.h3
-rw-r--r--indra/newview/llsettingswater.cpp65
-rw-r--r--indra/newview/llsettingswater.h1
-rw-r--r--indra/newview/llvosky.cpp2
9 files changed, 607 insertions, 69 deletions
diff --git a/indra/newview/llsettingsbase.cpp b/indra/newview/llsettingsbase.cpp
index c538cbe320..904d0dd07c 100644
--- a/indra/newview/llsettingsbase.cpp
+++ b/indra/newview/llsettingsbase.cpp
@@ -248,20 +248,6 @@ LLSD LLSettingsBase::cloneSettings() const
return combineSDMaps(mSettings, LLSD());
}
-LLSettingsBase::ptr_t LLSettingsBase::buildBlend(const ptr_t &begin, const ptr_t &end, F32 blendf)
-{
-// if (begin->getSettingType() != end->getSettingType())
-// {
-// LL_WARNS("SETTINGS") << "Attempt to blend settings of different types! " <<
-// begin->getSettingType() << "<->" << end->getSettingType() << LL_ENDL;
-//
-// return LLSettingsBase::ptr_t();
-// }
-
-// return begin->blend(end, blendf);
- return LLSettingsBase::ptr_t();
-}
-
void LLSettingsBase::exportSettings(std::string name) const
{
LLSD exprt = LLSDMap("type", LLSD::String(getSettingType()))
@@ -279,7 +265,6 @@ void LLSettingsBase::exportSettings(std::string name) const
presetsXML.close();
LL_DEBUGS() << "saved preset '" << name << "'; " << mSettings.size() << " settings" << LL_ENDL;
-
}
else
{
@@ -287,6 +272,326 @@ void LLSettingsBase::exportSettings(std::string name) const
}
}
+#ifdef VALIDATION_DEBUG
+namespace
+{
+ LLSD clone_llsd(LLSD value)
+ {
+ LLSD clone;
+
+ switch (value.type())
+ {
+// case LLSD::TypeMap:
+// newSettings[key_name] = combineSDMaps(value, LLSD());
+// break;
+ case LLSD::TypeArray:
+ clone = LLSD::emptyArray();
+ for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
+ {
+ clone.append( clone_llsd(*ita) );
+ }
+ break;
+ case LLSD::TypeInteger:
+ clone = LLSD::Integer(value.asInteger());
+ break;
+ case LLSD::TypeReal:
+ clone = LLSD::Real(value.asReal());
+ break;
+ case LLSD::TypeBoolean:
+ clone = LLSD::Boolean(value.asBoolean());
+ break;
+ case LLSD::TypeString:
+ clone = LLSD::String(value.asString());
+ break;
+ case LLSD::TypeUUID:
+ clone = LLSD::UUID(value.asUUID());
+ break;
+ case LLSD::TypeURI:
+ clone = LLSD::URI(value.asURI());
+ break;
+ case LLSD::TypeDate:
+ clone = LLSD::Date(value.asDate());
+ break;
+ //case LLSD::TypeBinary:
+ // break;
+ //default:
+ // newSettings[key_name] = value;
+ // break;
+ }
+
+ return clone;
+ }
+
+ bool compare_llsd(LLSD valA, LLSD valB)
+ {
+ if (valA.type() != valB.type())
+ return false;
+
+ switch (valA.type())
+ {
+ // case LLSD::TypeMap:
+ // newSettings[key_name] = combineSDMaps(value, LLSD());
+ // break;
+ case LLSD::TypeArray:
+ if (valA.size() != valB.size())
+ return false;
+
+ for (S32 idx = 0; idx < valA.size(); ++idx)
+ {
+ if (!compare_llsd(valA[idx], valB[idx]))
+ return false;
+ }
+ return true;
+
+ case LLSD::TypeInteger:
+ return valA.asInteger() == valB.asInteger();
+
+ case LLSD::TypeReal:
+ return is_approx_equal(valA.asReal(), valB.asReal());
+
+ case LLSD::TypeBoolean:
+ return valA.asBoolean() == valB.asBoolean();
+
+ case LLSD::TypeString:
+ return valA.asString() == valB.asString();
+
+ case LLSD::TypeUUID:
+ return valA.asUUID() == valB.asUUID();
+
+ case LLSD::TypeURI:
+ return valA.asString() == valB.asString();
+
+ case LLSD::TypeDate:
+ return valA.asDate() == valB.asDate();
+ }
+
+ return true;
+ }
+}
+#endif
+
+bool LLSettingsBase::validate()
+{
+ static Validator validateName(SETTING_NAME, false, LLSD::TypeString);
+ static Validator validateId(SETTING_ID, false, LLSD::TypeUUID);
+ validation_list_t validations = getValidationList();
+ stringset_t validated;
+ stringset_t strip;
+
+ // Fields common to all settings.
+ if (!validateName.verify(mSettings))
+ {
+ LL_WARNS("SETTINGS") << "Unable to validate name." << LL_ENDL;
+ mIsValid = false;
+ return false;
+ }
+ validated.insert(validateName.getName());
+
+ if (!validateId.verify(mSettings))
+ {
+ LL_WARNS("SETTINGS") << "Unable to validate Id." << LL_ENDL;
+ mIsValid = false;
+ return false;
+ }
+ validated.insert(validateId.getName());
+
+ // Fields for specific settings.
+ for (validation_list_t::iterator itv = validations.begin(); itv != validations.end(); ++itv)
+ {
+#ifdef VALIDATION_DEBUG
+ LLSD oldvalue;
+ if (mSettings.has((*itv).getName()))
+ {
+ oldvalue = clone_llsd(mSettings[(*itv).getName()]);
+ }
+#endif
+
+ if (!(*itv).verify(mSettings))
+ {
+ LL_WARNS("SETTINGS") << "Settings LLSD fails validation and could not be corrected!" << LL_ENDL;
+ mIsValid = false;
+ return false;
+ }
+ validated.insert((*itv).getName());
+
+#ifdef VALIDATION_DEBUG
+ if (!oldvalue.isUndefined())
+ {
+ if (!compare_llsd(mSettings[(*itv).getName()], oldvalue))
+ {
+ LL_WARNS("SETTINGS") << "Setting '" << (*itv).getName() << "' was changed: " << oldvalue << " -> " << mSettings[(*itv).getName()] << LL_ENDL;
+ }
+ }
+#endif
+ }
+
+ // strip extra entries
+ for (LLSD::map_iterator itm = mSettings.beginMap(); itm != mSettings.endMap(); ++itm)
+ {
+ if (validated.find((*itm).first) == validated.end())
+ {
+ LL_WARNS("SETTINGS") << "Stripping setting '" << (*itm).first << "'" << LL_ENDL;
+ strip.insert((*itm).first);
+ }
+ }
+
+ for (stringset_t::iterator its = strip.begin(); its != strip.end(); ++its)
+ {
+ mSettings.erase(*its);
+ }
+
+ return true;
+}
+
+//=========================================================================
+bool LLSettingsBase::Validator::verify(LLSD &data)
+{
+ if (!data.has(mName))
+ {
+ if (mRequired)
+ LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "'" << LL_ENDL;
+ return !mRequired;
+ }
+
+ if (data[mName].type() != mType)
+ {
+ LL_WARNS("SETTINGS") << "Setting '" << mName << "' is incorrect type." << LL_ENDL;
+ return false;
+ }
+
+ if (!mVerify.empty() && !mVerify(data[mName]))
+ {
+ LL_WARNS("SETTINGS") << "Setting '" << mName << "' fails validation." << LL_ENDL;
+ return false;
+ }
+
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyColor(LLSD &value)
+{
+ return (value.size() == 3 || value.size() == 4);
+}
+
+bool LLSettingsBase::Validator::verifyVector(LLSD &value, S32 length)
+{
+ return (value.size() == length);
+}
+
+bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length)
+{
+ if (value.size() != length)
+ return false;
+
+ LLSD newvector;
+
+ switch (length)
+ {
+ case 2:
+ {
+ LLVector2 vect(value);
+
+ if (is_approx_equal(vect.normalize(), 1.0f))
+ return true;
+ newvector = vect.getValue();
+ break;
+ }
+ case 3:
+ {
+ LLVector3 vect(value);
+
+ if (is_approx_equal(vect.normalize(), 1.0f))
+ return true;
+ newvector = vect.getValue();
+ break;
+ }
+ case 4:
+ {
+ LLVector4 vect(value);
+
+ if (is_approx_equal(vect.normalize(), 1.0f))
+ return true;
+ newvector = vect.getValue();
+ break;
+ }
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals)
+{
+ for (S32 index = 0; index < value.size(); ++index)
+ {
+ if (minvals[index].asString() != "*")
+ {
+ if (minvals[index].asReal() > value[index].asReal())
+ {
+ value[index] = minvals[index].asReal();
+ }
+ }
+ if (maxvals[index].asString() != "*")
+ {
+ if (maxvals[index].asReal() < value[index].asReal())
+ {
+ value[index] = maxvals[index].asReal();
+ }
+ }
+ }
+
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value)
+{
+ return (value.size() == 4);
+}
+
+bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value)
+{
+ if (value.size() != 4)
+ return false;
+
+ LLQuaternion quat(value);
+
+ if (is_approx_equal(quat.normalize(), 1.0f))
+ return true;
+
+ LLSD newquat = quat.getValue();
+ for (S32 index = 0; index < 4; ++index)
+ {
+ value[index] = newquat[index];
+ }
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range)
+{
+ F32 real = value.asReal();
+
+ F32 clampedval = llclamp(LLSD::Real(real), range[0].asReal(), range[1].asReal());
+
+ if (is_approx_equal(clampedval, real))
+ return true;
+
+ value = LLSD::Real(clampedval);
+ return true;
+}
+
+bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range)
+{
+ S32 ival = value.asInteger();
+
+ S32 clampedval = llclamp(LLSD::Integer(ival), range[0].asInteger(), range[1].asInteger());
+
+ if (clampedval == ival)
+ return true;
+
+ value = LLSD::Integer(clampedval);
+ return true;
+}
//=========================================================================
diff --git a/indra/newview/llsettingsbase.h b/indra/newview/llsettingsbase.h
index bf4053a4b1..d32fcb26e8 100644
--- a/indra/newview/llsettingsbase.h
+++ b/indra/newview/llsettingsbase.h
@@ -41,7 +41,9 @@
#include "llquaternion.h"
#include "v4color.h"
-class LLSettingsBase: private boost::noncopyable
+class LLSettingsBase :
+ public boost::enable_shared_from_this<LLSettingsBase>,
+ private boost::noncopyable
{
friend class LLEnvironment;
friend class LLSettingsDay;
@@ -59,8 +61,6 @@ public:
//---------------------------------------------------------------------
virtual std::string getSettingType() const = 0;
- static ptr_t buildBlend(const ptr_t &begin, const ptr_t &end, F32 blendf);
-
//---------------------------------------------------------------------
// Settings status
inline bool hasSetting(const std::string &param) const { return mSettings.has(param); }
@@ -153,13 +153,50 @@ public:
virtual void blend(const ptr_t &end, F32 blendf) = 0;
+ virtual bool validate();
+
protected:
+ class Validator
+ {
+ public:
+ typedef boost::function<bool(LLSD &)> verify_pr;
+
+ Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr()) :
+ mName(name),
+ mRequired(required),
+ mType(type),
+ mVerify(verify)
+ { }
+
+ std::string getName() const { return mName; }
+ bool isRequired() const { return mRequired; }
+ LLSD::Type getType() const { return mType; }
+
+ bool verify(LLSD &data);
+
+ // Some basic verifications
+ static bool verifyColor(LLSD &value);
+ static bool verifyVector(LLSD &value, S32 length);
+ static bool verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals);
+ static bool verifyVectorNormalized(LLSD &value, S32 length);
+ static bool verifyQuaternion(LLSD &value);
+ static bool verifyQuaternionNormal(LLSD &value);
+ static bool verifyFloatRange(LLSD &value, LLSD range);
+ static bool verifyIntegerRange(LLSD &value, LLSD range);
+
+ private:
+ std::string mName;
+ bool mRequired;
+ LLSD::Type mType;
+ verify_pr mVerify;
+ };
+ typedef std::vector<Validator> validation_list_t;
+
LLSettingsBase();
LLSettingsBase(const LLSD setting);
typedef std::set<std::string> stringset_t;
-
-
+
// combining settings objects. Customize for specific setting types
virtual void lerpSettings(const LLSettingsBase &other, F32 mix);
LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, F32 mix) const;
@@ -176,12 +213,15 @@ protected:
// Calculate any custom settings that may need to be cached.
virtual void updateSettings() { mDirty = false; };
+ virtual validation_list_t getValidationList() const = 0;
+
// Apply any settings that need special handling.
virtual void applySpecial(void *) { };
virtual parammapping_t getParameterMap() const { return parammapping_t(); }
LLSD mSettings;
+ bool mIsValid;
LLSD cloneSettings() const;
diff --git a/indra/newview/llsettingsdaycycle.cpp b/indra/newview/llsettingsdaycycle.cpp
index da384304d6..391aeddf1c 100644
--- a/indra/newview/llsettingsdaycycle.cpp
+++ b/indra/newview/llsettingsdaycycle.cpp
@@ -113,7 +113,6 @@ const std::string LLSettingsDay::SETTING_DAYLENGTH("day_length");
const std::string LLSettingsDay::SETTING_KEYID("key_id");
const std::string LLSettingsDay::SETTING_KEYNAME("key_name");
const std::string LLSettingsDay::SETTING_KEYKFRAME("key_keyframe");
-const std::string LLSettingsDay::SETTING_NAME("name");
const std::string LLSettingsDay::SETTING_TRACKS("tracks");
//const S64 LLSettingsDayCycle::MINIMUM_DAYLENGTH( 300); // 5 mins
@@ -123,6 +122,7 @@ const S64 LLSettingsDay::MAXIMUM_DAYLENGTH(604800); // 7 days
const S32 LLSettingsDay::TRACK_WATER(0); // water track is 0
const S32 LLSettingsDay::TRACK_MAX(5); // 5 tracks, 4 skys, 1 water
+const S32 LLSettingsDay::FRAME_MAX(56);
//=========================================================================
LLSettingsDay::LLSettingsDay(const LLSD &data) :
@@ -178,7 +178,10 @@ LLSettingsDay::ptr_t LLSettingsDay::buildFromLegacyPreset(const std::string &nam
LLSettingsDay::ptr_t dayp = boost::make_shared<LLSettingsDay>(newsettings);
dayp->parseFromLLSD(dayp->mSettings);
- return dayp;
+ if (dayp->validate())
+ return dayp;
+
+ return LLSettingsDay::ptr_t();
}
LLSettingsDay::ptr_t LLSettingsDay::buildFromLegacyMessage(const LLUUID &regionId, LLSD daycycle, LLSD skydefs, LLSD waterdef)
@@ -195,9 +198,9 @@ LLSettingsDay::ptr_t LLSettingsDay::buildFromLegacyMessage(const LLUUID &regionI
LL_WARNS("WindlightCaps") << "created region sky '" << name << "'" << LL_ENDL;
}
- LLSettingsDay::ptr_t day = buildFromLegacyPreset("Region (legacy)", daycycle);
+ LLSettingsDay::ptr_t dayp = buildFromLegacyPreset("Region (legacy)", daycycle);
- day->setWaterAtKeyframe(water, 0.0f);
+ dayp->setWaterAtKeyframe(water, 0.0f);
for (LLSD::array_iterator ita = daycycle.beginArray(); ita != daycycle.endArray(); ++ita)
{
@@ -208,14 +211,17 @@ LLSettingsDay::ptr_t LLSettingsDay::buildFromLegacyMessage(const LLUUID &regionI
if (it == skys.end())
continue;
- day->setSkyAtKeyframe(boost::static_pointer_cast<LLSettingsSky>((*it).second), frame, 1);
+ dayp->setSkyAtKeyframe(boost::static_pointer_cast<LLSettingsSky>((*it).second), frame, 1);
LL_WARNS("WindlightCaps") << "Added '" << name << "' to region day cycle at " << frame << LL_ENDL;
}
- day->mHasParsed = true;
+ dayp->mHasParsed = true;
- return day;
+ if (dayp->validate())
+ return dayp;
+
+ return LLSettingsDay::ptr_t();
}
LLSettingsDay::ptr_t LLSettingsDay::buildDefaultDayCycle()
@@ -225,7 +231,10 @@ LLSettingsDay::ptr_t LLSettingsDay::buildDefaultDayCycle()
LLSettingsDay::ptr_t dayp = boost::make_shared<LLSettingsDay>(settings);
dayp->parseFromLLSD(dayp->mSettings);
- return dayp;
+ if (dayp->validate())
+ return dayp;
+
+ return LLSettingsDay::ptr_t();
}
void LLSettingsDay::parseFromLLSD(LLSD &data)
@@ -277,6 +286,71 @@ void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F32 mix)
LL_ERRS("DAYCYCLE") << "Day cycles are not blendable!" << LL_ENDL;
}
+namespace
+{
+ bool validateDayCycleTrack(LLSD &value)
+ {
+ // Trim extra tracks.
+ while (value.size() > LLSettingsDay::TRACK_MAX)
+ {
+ value.erase(value.size() - 1);
+ }
+
+ for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track)
+ {
+ S32 index = 0;
+ while (index < (*track).size())
+ {
+ if (index >= LLSettingsDay::FRAME_MAX)
+ {
+ (*track).erase(index);
+ continue;
+ }
+
+ if (!(*track)[index].has(LLSettingsDay::SETTING_KEYKFRAME) ||
+ !(*track)[index][LLSettingsDay::SETTING_KEYKFRAME].isReal())
+ {
+ (*track).erase(index);
+ continue;
+ }
+
+ if (!(*track)[index].has(LLSettingsDay::SETTING_KEYNAME) &&
+ !(*track)[index].has(LLSettingsDay::SETTING_KEYID))
+ {
+ (*track).erase(index);
+ continue;
+ }
+
+ F32 frame = (*track)[index][LLSettingsDay::SETTING_KEYKFRAME].asReal();
+ if ((frame < 0.0) || (frame > 1.0))
+ {
+ frame = llclamp(frame, 0.0f, 1.0f);
+ (*track)[index][LLSettingsDay::SETTING_KEYKFRAME] = frame;
+ }
+ ++index;
+ }
+
+ }
+ return true;
+ }
+}
+
+LLSettingsDay::validation_list_t LLSettingsDay::getValidationList() const
+{
+ static validation_list_t validation;
+
+ if (validation.empty())
+ {
+ validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray,
+ &validateDayCycleTrack));
+ validation.push_back(Validator(SETTING_DAYLENGTH, false, LLSD::TypeInteger,
+ boost::bind(&Validator::verifyIntegerRange, _1,
+ LLSD(LLSDArray(LLSD::Integer(MINIMUM_DAYLENGTH))(LLSD::Integer(MAXIMUM_DAYLENGTH))))));
+ }
+
+ return validation;
+}
+
//=========================================================================
F32 LLSettingsDay::secondsToKeyframe(S64Seconds seconds)
{
diff --git a/indra/newview/llsettingsdaycycle.h b/indra/newview/llsettingsdaycycle.h
index ba3d592bd6..804d7aee26 100644
--- a/indra/newview/llsettingsdaycycle.h
+++ b/indra/newview/llsettingsdaycycle.h
@@ -43,7 +43,6 @@ public:
static const std::string SETTING_KEYID;
static const std::string SETTING_KEYNAME;
static const std::string SETTING_KEYKFRAME;
- static const std::string SETTING_NAME;
static const std::string SETTING_TRACKS;
static const S64 MINIMUM_DAYLENGTH;
@@ -51,6 +50,7 @@ public:
static const S32 TRACK_WATER;
static const S32 TRACK_MAX;
+ static const S32 FRAME_MAX;
typedef std::map<F32, LLSettingsBase::ptr_t> CycleTrack_t;
typedef std::vector<CycleTrack_t> CycleList_t;
@@ -110,6 +110,8 @@ protected:
virtual void updateSettings();
+ virtual validation_list_t getValidationList() const;
+
private:
LLSettingsBlender::ptr_t mSkyBlender; // convert to [] for altitudes
LLSettingsBlender::ptr_t mWaterBlender;
diff --git a/indra/newview/llsettingssky.cpp b/indra/newview/llsettingssky.cpp
index ccab35f669..1109099ff5 100644
--- a/indra/newview/llsettingssky.cpp
+++ b/indra/newview/llsettingssky.cpp
@@ -90,7 +90,6 @@ const std::string LLSettingsSky::SETTING_LEGACY_EAST_ANGLE("east_angle");
const std::string LLSettingsSky::SETTING_LEGACY_ENABLE_CLOUD_SCROLL("enable_cloud_scroll");
const std::string LLSettingsSky::SETTING_LEGACY_SUN_ANGLE("sun_angle");
-
//=========================================================================
LLSettingsSky::LLSettingsSky(const LLSD &data) :
LLSettingsBase(data)
@@ -150,6 +149,86 @@ LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const
return slepSet;
}
+LLSettingsSky::validation_list_t LLSettingsSky::getValidationList() const
+{
+ static validation_list_t validation;
+
+ if (validation.empty())
+ { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
+ // copy constructor for LLSDArray. Directly binding the LLSDArray as
+ // a parameter without first wrapping it in a pure LLSD object will result
+ // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
+
+ validation.push_back(Validator(SETTING_AMBIENT, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ validation.push_back(Validator(SETTING_BLOOM_TEXTUREID, true, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_BLUE_DENSITY, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
+ validation.push_back(Validator(SETTING_BLUE_HORIZON, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(2.0f)(2.0f)(2.0f)("*")))));
+ validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
+ validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(1.68841f)(1.0f)(1.0f)("*")))));
+ validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(1.68841f)(1.0f)(1.0f)("*")))));
+ validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.001f)(0.999f)))));
+ validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)),
+ LLSD(LLSDArray(20.0f)(20.0f)))));
+ validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_DENSITY_MULTIPLIER, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.0009f)))));
+ validation.push_back(Validator(SETTING_DISTANCE_MULTIPLIER, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(100.0f)))));
+ validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(2000.0f)))));
+ validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(10.0f)))));
+ validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.2f)("*")(-2.5f)("*")),
+ LLSD(LLSDArray(20.0f)("*")(0.0f)("*")))));
+ validation.push_back(Validator(SETTING_HAZE_DENSITY, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(4.0f)))));
+ validation.push_back(Validator(SETTING_HAZE_HORIZON, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_LIGHT_NORMAL, false, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorNormalized, _1, 3)));
+ validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(4000.0f)))));
+ validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
+ validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+ validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
+ LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ validation.push_back(Validator(SETTING_SUN_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
+ validation.push_back(Validator(SETTING_SUN_TEXUTUREID, false, LLSD::TypeUUID));
+ }
+
+ return validation;
+}
LLSettingsSky::ptr_t LLSettingsSky::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings)
{
@@ -231,7 +310,7 @@ LLSettingsSky::ptr_t LLSettingsSky::buildFromLegacyPreset(const std::string &nam
}
if (oldsettings.has(SETTING_LIGHT_NORMAL))
{
- newsettings[SETTING_LIGHT_NORMAL] = LLVector4(oldsettings[SETTING_LIGHT_NORMAL]).getValue();
+ newsettings[SETTING_LIGHT_NORMAL] = LLVector3(oldsettings[SETTING_LIGHT_NORMAL]).getValue();
}
if (oldsettings.has(SETTING_MAX_Y))
{
@@ -246,18 +325,6 @@ LLSettingsSky::ptr_t LLSettingsSky::buildFromLegacyPreset(const std::string &nam
newsettings[SETTING_SUNLIGHT_COLOR] = LLColor4(oldsettings[SETTING_SUNLIGHT_COLOR]).getValue();
}
-
-// dfltsetting[SETTING_DOME_OFFSET] = LLSD::Real(0.96f);
-// dfltsetting[SETTING_DOME_RADIUS] = LLSD::Real(15000.f);
-//
-// dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue();
-// dfltsetting[SETTING_SUN_ROTATION] = sunquat.getValue();
-//
-// dfltsetting[SETTING_BLOOM_TEXTUREID] = LLUUID::null;
-// dfltsetting[SETTING_CLOUD_TEXTUREID] = LLUUID::null;
-// dfltsetting[SETTING_MOON_TEXTUREID] = IMG_SUN; // gMoonTextureID; // These two are returned by the login... wow!
-// dfltsetting[SETTING_SUN_TEXUTUREID] = IMG_MOON; // gSunTextureID;
-
if (oldsettings.has(SETTING_LEGACY_EAST_ANGLE) && oldsettings.has(SETTING_LEGACY_SUN_ANGLE))
{ // convert the east and sun angles into a quaternion.
F32 azimuth = oldsettings[SETTING_LEGACY_EAST_ANGLE].asReal();
@@ -275,7 +342,10 @@ LLSettingsSky::ptr_t LLSettingsSky::buildFromLegacyPreset(const std::string &nam
LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(newsettings);
- return skyp;
+ if (skyp->validate())
+ return skyp;
+
+ return LLSettingsSky::ptr_t();
}
LLSettingsSky::ptr_t LLSettingsSky::buildDefaultSky()
@@ -283,8 +353,10 @@ LLSettingsSky::ptr_t LLSettingsSky::buildDefaultSky()
LLSD settings = LLSettingsSky::defaults();
LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(settings);
+ if (skyp->validate())
+ return skyp;
- return skyp;
+ return LLSettingsSky::ptr_t();
}
LLSettingsSky::ptr_t LLSettingsSky::buildClone()
@@ -293,23 +365,11 @@ LLSettingsSky::ptr_t LLSettingsSky::buildClone()
LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(settings);
- return skyp;
-}
+ if (skyp->validate())
+ return skyp;
-// Settings status
-
-// LLSettingsSky::ptr_t LLSettingsSky::blend(const LLSettingsSky::ptr_t &other, F32 mix) const
-// {
-// LL_RECORD_BLOCK_TIME(FTM_BLEND_SKYVALUES);
-// LL_INFOS("WINDLIGHT", "SKY", "EEP") << "Blending new sky settings object." << LL_ENDL;
-//
-// LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(mSettings);
-// // the settings in the initial constructor are references to this' settings block.
-// // They will be replaced in the following lerp
-// skyp->lerpSettings(*other, mix);
-//
-// return skyp;
-// }
+ return LLSettingsSky::ptr_t();
+}
LLSD LLSettingsSky::defaults()
@@ -339,7 +399,7 @@ LLSD LLSettingsSky::defaults()
dfltsetting[SETTING_GLOW] = LLColor4(5.000, 0.0010, -0.4799, 1.0).getValue();
dfltsetting[SETTING_HAZE_DENSITY] = LLSD::Real(0.6999);
dfltsetting[SETTING_HAZE_HORIZON] = LLSD::Real(0.1899);
- dfltsetting[SETTING_LIGHT_NORMAL] = LLVector4(0.0000, 0.9126, -0.4086, 0.0000).getValue();
+ dfltsetting[SETTING_LIGHT_NORMAL] = LLVector3(0.0000, 0.9126, -0.4086).getValue();
dfltsetting[SETTING_MAX_Y] = LLSD::Real(1605);
dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue();
dfltsetting[SETTING_NAME] = std::string("_default_");
diff --git a/indra/newview/llsettingssky.h b/indra/newview/llsettingssky.h
index ade5a06553..8efadf44b0 100644
--- a/indra/newview/llsettingssky.h
+++ b/indra/newview/llsettingssky.h
@@ -416,6 +416,9 @@ protected:
virtual stringset_t getSlerpKeys() const;
+ virtual validation_list_t getValidationList() const;
+
+
virtual void updateSettings();
virtual parammapping_t getParameterMap() const;
diff --git a/indra/newview/llsettingswater.cpp b/indra/newview/llsettingswater.cpp
index 70688ee1ef..dda9265903 100644
--- a/indra/newview/llsettingswater.cpp
+++ b/indra/newview/llsettingswater.cpp
@@ -114,7 +114,6 @@ LLSD LLSettingsWater::defaults()
return dfltsetting;
}
-
LLSettingsWater::ptr_t LLSettingsWater::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings)
{
LLSD newsettings(defaults());
@@ -173,25 +172,34 @@ LLSettingsWater::ptr_t LLSettingsWater::buildFromLegacyPreset(const std::string
LLSettingsWater::ptr_t waterp = boost::make_shared<LLSettingsWater>(newsettings);
- return waterp;
+ if (waterp->validate())
+ return waterp;
+
+ return LLSettingsWater::ptr_t();
}
LLSettingsWater::ptr_t LLSettingsWater::buildDefaultWater()
{
LLSD settings = LLSettingsWater::defaults();
- LLSettingsWater::ptr_t skyp = boost::make_shared<LLSettingsWater>(settings);
+ LLSettingsWater::ptr_t waterp = boost::make_shared<LLSettingsWater>(settings);
- return skyp;
+ if (waterp->validate())
+ return waterp;
+
+ return LLSettingsWater::ptr_t();
}
LLSettingsWater::ptr_t LLSettingsWater::buildClone()
{
LLSD settings = cloneSettings();
- LLSettingsWater::ptr_t skyp = boost::make_shared<LLSettingsWater>(settings);
+ LLSettingsWater::ptr_t waterp = boost::make_shared<LLSettingsWater>(settings);
+
+ if (waterp->validate())
+ return waterp;
- return skyp;
+ return LLSettingsWater::ptr_t();
}
void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F32 blendf)
@@ -202,6 +210,51 @@ void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F32 blendf)
replaceSettings(blenddata);
}
+LLSettingsWater::validation_list_t LLSettingsWater::getValidationList() const
+{
+ static validation_list_t validation;
+
+ if (validation.empty())
+ { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
+ // copy constructor for LLSDArray. Directly binding the LLSDArray as
+ // a parameter without first wrapping it in a pure LLSD object will result
+ // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
+
+ validation.push_back(Validator(SETTING_BLUR_MULTIPILER, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.16f)))));
+ validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)),
+ LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f)))));
+ validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1.0f)(1024.0f)))));
+ validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID));
+ validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(0.0f)(0.0f)(0.0f)),
+ LLSD(LLSDArray(10.0f)(10.0f)(10.0f)))));
+ validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
+ boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(-4.0f)(-4.0f)),
+ LLSD(LLSDArray(4.0f)(4.0f)))));
+ validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
+ boost::bind(&Validator::verifyVectorMinMax, _1,
+ LLSD(LLSDArray(-4.0f)(-4.0f)),
+ LLSD(LLSDArray(4.0f)(4.0f)))));
+ }
+
+ return validation;
+}
//=========================================================================
diff --git a/indra/newview/llsettingswater.h b/indra/newview/llsettingswater.h
index 1550ba4004..a62fa355de 100644
--- a/indra/newview/llsettingswater.h
+++ b/indra/newview/llsettingswater.h
@@ -209,6 +209,7 @@ protected:
virtual void applySpecial(void *);
+ virtual validation_list_t getValidationList() const;
private:
static const std::string SETTING_LEGACY_BLUR_MULTIPILER;
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 0c211b259c..2ab273df91 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -833,7 +833,7 @@ void LLVOSky::calcAtmospherics(void)
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
mSun.setColor(psky->getSunlightColor());
- mMoon.setColor(LLColor3(2.0f, 2.0f, 2.0f));
+ mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
mSun.renewDirection();
mSun.renewColor();