diff options
author | Rider Linden <rider@lindenlab.com> | 2017-11-17 13:04:28 -0800 |
---|---|---|
committer | Rider Linden <rider@lindenlab.com> | 2017-11-17 13:04:28 -0800 |
commit | 0bf6386c61c0c28b298c2cccd82c786f754024af (patch) | |
tree | 110ff24a45be3554fb64ae9eca06fc1961cc6efc | |
parent | 35873f5963791af08a9951624dc96481a71fa1d7 (diff) |
Now with validation.
-rw-r--r-- | indra/newview/llsettingsbase.cpp | 335 | ||||
-rw-r--r-- | indra/newview/llsettingsbase.h | 50 | ||||
-rw-r--r-- | indra/newview/llsettingsdaycycle.cpp | 90 | ||||
-rw-r--r-- | indra/newview/llsettingsdaycycle.h | 4 | ||||
-rw-r--r-- | indra/newview/llsettingssky.cpp | 126 | ||||
-rw-r--r-- | indra/newview/llsettingssky.h | 3 | ||||
-rw-r--r-- | indra/newview/llsettingswater.cpp | 65 | ||||
-rw-r--r-- | indra/newview/llsettingswater.h | 1 | ||||
-rw-r--r-- | indra/newview/llvosky.cpp | 2 |
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 ¶m) 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 ®ionId, LLSD daycycle, LLSD skydefs, LLSD waterdef) @@ -195,9 +198,9 @@ LLSettingsDay::ptr_t LLSettingsDay::buildFromLegacyMessage(const LLUUID ®ionI 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 ®ionI 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(); |