diff options
| author | Dave Simmons <simon@lindenlab.com> | 2009-03-20 20:00:47 +0000 | 
|---|---|---|
| committer | Dave Simmons <simon@lindenlab.com> | 2009-03-20 20:00:47 +0000 | 
| commit | 24b26d71ee01211aa796b8061b66ec06a133e4ce (patch) | |
| tree | 96bffcd019c933ad3ebbfd5f096968108b22aab5 /indra/newview | |
| parent | 5dfd435872e36445dcc82f99443dfc5a7ee0805a (diff) | |
svn merge -r113004:115000 svn+ssh://svn.lindenlab.com/svn/linden/branches/server/server-1.26
Merge latest 1.26 into trunk
Diffstat (limited to 'indra/newview')
31 files changed, 1339 insertions, 177 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1ca1b4f915..ac05a7dbd7 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -11,6 +11,7 @@ include(ELFIO)  include(FMOD)  include(OPENAL)  include(FindOpenGL) +include(LLAddBuildTest)  include(LLAudio)  include(LLCharacter)  include(LLCommon) @@ -64,6 +65,7 @@ include_directories(  set(viewer_SOURCE_FILES      llagent.cpp +    llagentaccess.cpp      llagentdata.cpp      llagentlanguage.cpp      llagentpilot.cpp @@ -466,6 +468,7 @@ set(viewer_HEADER_FILES      ViewerInstall.cmake      llagent.h +    llagentaccess.h      llagentdata.h      llagentlanguage.h      llagentpilot.h @@ -1566,3 +1569,5 @@ endif (DARWIN)  if (INSTALL)    include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)  endif (INSTALL) + +ADD_VIEWER_BUILD_TEST(llagentaccess viewer) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 41120522d5..d90882fb96 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4867,18 +4867,18 @@        <key>Value</key>        <real>0.0</real>      </map> -	<key>InstallLanguage</key> -	<map> -		<key>Comment</key> -		<string>Language passed from installer (for UI)</string> -		<key>Persist</key> -		<integer>1</integer> -		<key>Type</key> -		<string>String</string> -		<key>Value</key> -		<string>default</string> -	</map> -	<key>InventoryAutoOpenDelay</key> +    <key>InstallLanguage</key> +    <map> +      <key>Comment</key> +      <string>Language passed from installer (for UI)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string>default</string> +    </map> +    <key>InventoryAutoOpenDelay</key>      <map>        <key>Comment</key>        <string>Seconds before automatically opening inventory when mouse is over inventory button when performing inventory drag and drop</string> @@ -6410,6 +6410,17 @@        <key>Value</key>        <real>6.0</real>      </map> +	<key>PreferredMaturity</key> +    <map> +      <key>Comment</key> +      <string>Setting for the user's preferred maturity level.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>U32</string> +      <key>Value</key> +	  <integer>13</integer> +    </map>      <key>PreviewAnimRect</key>      <map>        <key>Comment</key> @@ -7966,10 +7977,12 @@        <string>URL to load for empty searches</string>        <key>Persist</key>        <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer>        <key>Type</key>        <string>String</string>        <key>Value</key> -      <string>http://secondlife.com/app/search/index.php?</string> +      <string>http://search.secondlife.com/client_search.php?</string>      </map>      <key>SearchURLQuery</key>      <map> @@ -7977,10 +7990,12 @@        <string>URL to use for searches</string>        <key>Persist</key>        <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer>        <key>Type</key>        <string>String</string>        <key>Value</key> -      <string>http://secondlife.com/app/search/search_proxy.php?q=[QUERY]&s=[COLLECTION]&</string> +      <string>http://search.secondlife.com/client_search.php?q=[QUERY]&s=[COLLECTION]&</string>      </map>      <key>SearchURLSuffix2</key>      <map> @@ -7988,10 +8003,12 @@        <string>Parameters added to end of search queries</string>        <key>Persist</key>        <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer>        <key>Type</key>        <string>String</string>        <key>Value</key> -      <string>lang=[LANG]&m=[MATURE]&t=[TEEN]&region=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]</string> +      <string>lang=[LANG]&mat=[MATURITY]&t=[TEEN]&region=[REGION]&x=[X]&y=[Y]&z=[Z]&session=[SESSION]</string>      </map>      <key>SelectMovableOnly</key>      <map> @@ -8301,45 +8318,209 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>ShowPGSearchAll</key> +    <map> +      <key>Comment</key> +      <string>Display results of search All that are flagged as PG</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    <key>ShowMatureSearchAll</key> +    <map> +      <key>Comment</key> +      <string>Display results of search All that are flagged as mature</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowAdultSearchAll</key> +    <map> +      <key>Comment</key> +      <string>Display results of search All that are flagged as adult</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowPGGroups</key> +    <map> +      <key>Comment</key> +      <string>Display results of find groups that are flagged as PG</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    <key>ShowMatureGroups</key> +    <map> +      <key>Comment</key> +      <string>Display results of find groups that are flagged as mature</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowAdultGroups</key> +    <map> +      <key>Comment</key> +      <string>Display results of find groups that are flagged as adult</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowPGClassifieds</key> +    <map> +      <key>Comment</key> +      <string>Display results of find classifieds that are flagged as PG</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>ShowMatureClassifieds</key>      <map>        <key>Comment</key>        <string>Display results of find classifieds that are flagged as mature</string>        <key>Persist</key>        <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowAdultClassifieds</key> +    <map> +      <key>Comment</key> +      <string>Display results of find classifieds that are flagged as adult</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer>        <key>Type</key>        <string>Boolean</string>        <key>Value</key>        <integer>0</integer>      </map> +    <key>ShowPGEvents</key> +    <map> +      <key>Comment</key> +      <string>Display results of find events that are flagged as PG</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>ShowMatureEvents</key>      <map>        <key>Comment</key>        <string>Display results of find events that are flagged as mature</string>        <key>Persist</key>        <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer>        <key>Type</key>        <string>Boolean</string>        <key>Value</key>        <integer>0</integer>      </map> -    <key>ShowMatureFindAll</key> +    <key>ShowAdultEvents</key>      <map>        <key>Comment</key> -      <string>Display results of find all that are in mature sims</string> +      <string>Display results of find events that are flagged as adult</string>        <key>Persist</key>        <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer>        <key>Type</key>        <string>Boolean</string>        <key>Value</key>        <integer>0</integer>      </map> -    <key>ShowMatureGroups</key> +    <key>ShowPGLand</key>      <map>        <key>Comment</key> -      <string>Display results of find groups that are in flagged as mature</string> +      <string>Display results of find land sales that are flagged as PG</string>        <key>Persist</key>        <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map> +    <key>ShowMatureLand</key> +    <map> +      <key>Comment</key> +      <string>Display results of find land sales that are flagged as mature</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowAdultLand</key> +    <map> +      <key>Comment</key> +      <string>Display results of find land sales that are flagged as adult</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowPGSims</key> +    <map> +      <key>Comment</key> +      <string>Display results of find places or find popular that are in PG sims</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer>        <key>Type</key>        <string>Boolean</string>        <key>Value</key> @@ -8351,6 +8532,21 @@        <string>Display results of find places or find popular that are in mature sims</string>        <key>Persist</key>        <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>ShowAdultSims</key> +    <map> +      <key>Comment</key> +      <string>Display results of find places or find popular that are in adult sims</string> +      <key>Persist</key> +      <integer>1</integer> +	  <key>HideFromEditor</key> +	  <integer>1</integer>        <key>Type</key>        <string>Boolean</string>        <key>Value</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 858855fe18..a894bca619 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -283,7 +283,7 @@ LLAgent::LLAgent() :  	mbAlwaysRun(false),  	mbRunning(false), -	mAccess(SIM_ACCESS_PG), +	mAgentAccess(gSavedSettings),  	mTeleportState( TELEPORT_NONE ),  	mRegionp(NULL), @@ -387,9 +387,7 @@ LLAgent::LLAgent() :  	mHaveHomePosition(FALSE),  	mHomeRegionHandle( 0 ),  	mNearChatRadius(CHAT_NORMAL_RADIUS / 2.f), -	mAdminOverride(FALSE), -	mGodLevel( GOD_NOT ),  	mNextFidgetTime(0.f),  	mCurrentFidget(0),  	mFirstLogin(FALSE), @@ -4820,41 +4818,132 @@ void LLAgent::onAnimStop(const LLUUID& id)  BOOL LLAgent::isGodlike() const  { -#ifdef HACKED_GODLIKE_VIEWER -	return TRUE; -#else -	if(mAdminOverride) return TRUE; -	return mGodLevel > GOD_NOT; -#endif +	return mAgentAccess.isGodlike();  }  U8 LLAgent::getGodLevel() const  { -#ifdef HACKED_GODLIKE_VIEWER -	return GOD_MAINTENANCE; -#else -	if(mAdminOverride) return GOD_FULL; -	return mGodLevel; -#endif +	return mAgentAccess.getGodLevel(); +} + +bool LLAgent::wantsPGOnly() const +{ +	return mAgentAccess.wantsPGOnly(); +} + +bool LLAgent::canAccessMature() const +{ +	return mAgentAccess.canAccessMature(); +} + +bool LLAgent::canAccessAdult() const +{ +	return mAgentAccess.canAccessAdult(); +} + +bool LLAgent::prefersPG() const +{ +	return mAgentAccess.prefersPG(); +} + +bool LLAgent::prefersMature() const +{ +	return mAgentAccess.prefersMature(); +} +	 +bool LLAgent::prefersAdult() const +{ +	return mAgentAccess.prefersAdult();  }  bool LLAgent::isTeen() const  { -	return mAccess < SIM_ACCESS_MATURE; +	return mAgentAccess.isTeen(); +} + +bool LLAgent::isMature() const +{ +	return mAgentAccess.isMature(); +} + +bool LLAgent::isAdult() const +{ +	return mAgentAccess.isAdult();  }  void LLAgent::setTeen(bool teen)  { -	if (teen) -	{ -		mAccess = SIM_ACCESS_PG; -	} -	else +	mAgentAccess.setTeen(teen); +} + +//static  +int LLAgent::convertTextToMaturity(char text) +{ +	return LLAgentAccess::convertTextToMaturity(text); +} + +bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity) +{ +	// Update agent access preference on the server +	std::string url = getRegion()->getCapability("UpdateAgentInformation"); +	if (!url.empty())  	{ -		mAccess = SIM_ACCESS_MATURE; +		// Set new access preference +		LLSD access_prefs = LLSD::emptyMap(); +		if (preferredMaturity == SIM_ACCESS_PG) +		{ +			access_prefs["max"] = "PG"; +		} +		else if (preferredMaturity == SIM_ACCESS_MATURE) +		{ +			access_prefs["max"] = "M"; +		} +		if (preferredMaturity == SIM_ACCESS_ADULT) +		{ +			access_prefs["max"] = "A"; +		} +		 +		LLSD body = LLSD::emptyMap(); +		body["access_prefs"] = access_prefs; +		llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: " +		<< url << llendl; +		LLHTTPClient::post(url, body, new LLHTTPClient::Responder());    // Ignore response +		return true;  	} +	return false; +} + +BOOL LLAgent::getAdminOverride() const	 +{  +	return mAgentAccess.getAdminOverride();   } +void LLAgent::setMaturity(char text) +{ +	mAgentAccess.setMaturity(text); +} + +void LLAgent::setAdminOverride(BOOL b)	 +{  +	mAgentAccess.setAdminOverride(b); +} + +void LLAgent::setGodLevel(U8 god_level)	 +{  +	mAgentAccess.setGodLevel(god_level); +} + +void LLAgent::setAOTransition() +{ +	mAgentAccess.setTransition(); +} + +const LLAgentAccess& LLAgent::getAgentAccess() +{ +	return mAgentAccess; +} + +  void LLAgent::buildFullname(std::string& name) const  {  	if (mAvatarObject.notNull()) diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 9d08c94150..fefb2a1d0b 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -40,6 +40,7 @@  #include "llcontrol.h"  #include "llcoordframe.h"  #include "llevent.h" +#include "llagentaccess.h"  #include "llagentconstants.h"  #include "llanimationstates.h"  #include "lldbstrings.h" @@ -223,8 +224,8 @@ public:  	void			clearBusy();  	BOOL			getBusy() const; -	void			setAdminOverride(BOOL b)	{ mAdminOverride = b; } -	void			setGodLevel(U8 god_level)	{ mGodLevel = god_level; } +	void			setAdminOverride(BOOL b); +	void			setGodLevel(U8 god_level);  	void			setFirstLogin(BOOL b)		{ mFirstLogin = b; }  	void			setGenderChosen(BOOL b)		{ mGenderChosen = b; } @@ -250,8 +251,29 @@ public:  	BOOL			isGodlike() const;  	U8				getGodLevel() const; +	// note: this is a prime candidate for pulling out into a Maturity class +	// rather than just expose the preference setting, we're going to actually +	// expose what the client code cares about -- what the user should see +	// based on a combination of the is* and prefers* flags, combined with God bit. +	bool wantsPGOnly() const; +	bool canAccessMature() const; +	bool canAccessAdult() const; +	bool prefersPG() const; +	bool prefersMature() const; +	bool prefersAdult() const;  	bool isTeen() const; +	bool isMature() const; +	bool isAdult() const;  	void setTeen(bool teen); +	void setMaturity(char text); +	static int convertTextToMaturity(char text); +	bool sendMaturityPreferenceToServer(int preferredMaturity); +	 +	const LLAgentAccess&  getAgentAccess(); +	 +	// This function can go away after the AO transition (see llstartup.cpp) +	void setAOTransition(); +	  	BOOL			isGroupTitleHidden() const		{ return mHideGroupTitle; }  	BOOL			isGroupMember() const		{ return !mGroupID.isNull(); }		// This is only used for building titles!  	const LLUUID	&getGroupID() const			{ return mGroupID; } @@ -261,7 +283,7 @@ public:  	F32				getFocusObjectDist() const	{ return mFocusObjectDist; }  	BOOL			inPrelude();  	BOOL			canManageEstate() const; -	BOOL			getAdminOverride() const	{ return mAdminOverride; } +	BOOL			getAdminOverride() const;  	LLUUID			getLastChatter() const { return mLastChatterID; }  	bool			getAlwaysRun() const { return mbAlwaysRun; } @@ -741,8 +763,8 @@ private:  	bool mbAlwaysRun; // should the avatar run by default rather than walk  	bool mbRunning;	// is the avatar trying to run right now -	// Access or "maturity" level -	U8				mAccess;	// SIM_ACCESS_MATURE or SIM_ACCESS_PG +	LLAgentAccess   mAgentAccess; +	  	ETeleportState	mTeleportState;  	std::string		mTeleportMessage; @@ -865,10 +887,7 @@ private:  	LLFrameTimer	mChatTimer;  	LLUUID			mLastChatterID;  	F32				mNearChatRadius; -	BOOL			mAdminOverride; -	// See indra_constants.h for values. -	U8				mGodLevel;  	LLFrameTimer	mFidgetTimer;  	LLFrameTimer	mFocusObjectFadeTimer;  	F32				mNextFidgetTime; diff --git a/indra/newview/llagentaccess.cpp b/indra/newview/llagentaccess.cpp new file mode 100644 index 0000000000..a4fbc04855 --- /dev/null +++ b/indra/newview/llagentaccess.cpp @@ -0,0 +1,154 @@ +/**  + * @file llagentaccess.cpp + * @brief LLAgentAccess class implementation - manages maturity and godmode info + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * Copyright (c) 2001-2009, Linden Research, Inc. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llagentaccess.h" +#include "indra_constants.h" +#include "llcontrolgroupreader.h" + +LLAgentAccess::LLAgentAccess(LLControlGroupReader& savedSettings) : +	mSavedSettings(savedSettings), +	mAccess(SIM_ACCESS_PG), +	mAdminOverride(false), +	mGodLevel(GOD_NOT), +	mAOTransition(false) +{ +} + +bool LLAgentAccess::getAdminOverride() const	 +{  +	return mAdminOverride;  +} + +void LLAgentAccess::setAdminOverride(bool b) +{  +	mAdminOverride = b;  +} + +void LLAgentAccess::setGodLevel(U8 god_level) +{  +	mGodLevel = god_level;  +} + +bool LLAgentAccess::isGodlike() const +{ +#ifdef HACKED_GODLIKE_VIEWER +	return true; +#else +	if(mAdminOverride) return true; +	return mGodLevel > GOD_NOT; +#endif +} + +U8 LLAgentAccess::getGodLevel() const +{ +#ifdef HACKED_GODLIKE_VIEWER +	return GOD_MAINTENANCE; +#else +	if(mAdminOverride) return GOD_FULL; +	return mGodLevel; +#endif +} + +bool LLAgentAccess::wantsPGOnly() const +{ +	return (prefersPG() || isTeen()) && !isGodlike(); +} + +bool LLAgentAccess::canAccessMature() const +{ +	// if you prefer mature, you're either mature or adult, and +	// therefore can access all mature content +	return isGodlike() || (prefersMature() && !isTeen()); +} + +bool LLAgentAccess::canAccessAdult() const +{ +	// if you prefer adult, you must BE adult. +	return isGodlike() || (prefersAdult() && isAdult()); +} + +bool LLAgentAccess::prefersPG() const +{ +	U32 access = mSavedSettings.getU32("PreferredMaturity"); +	return access < SIM_ACCESS_MATURE; +} + +bool LLAgentAccess::prefersMature() const +{ +	U32 access = mSavedSettings.getU32("PreferredMaturity"); +	return access >= SIM_ACCESS_MATURE; +} + +bool LLAgentAccess::prefersAdult() const +{ +	U32 access = mSavedSettings.getU32("PreferredMaturity"); +	return access >= SIM_ACCESS_ADULT; +} + +bool LLAgentAccess::isTeen() const +{ +	return mAccess < SIM_ACCESS_MATURE; +} + +bool LLAgentAccess::isMature() const +{ +	return mAccess >= SIM_ACCESS_MATURE; +} + +bool LLAgentAccess::isAdult() const +{ +	return mAccess >= SIM_ACCESS_ADULT; +} + +void LLAgentAccess::setTeen(bool teen) +{ +	if (teen) +	{ +		mAccess = SIM_ACCESS_PG; +	} +	else +	{ +		mAccess = SIM_ACCESS_MATURE; +	} +} + +//static  +int LLAgentAccess::convertTextToMaturity(char text) +{ +	if ('A' == text) +	{ +		return SIM_ACCESS_ADULT; +	} +	else if ('M'== text) +	{ +		return SIM_ACCESS_MATURE; +	} +	else if ('P'== text) +	{ +		return SIM_ACCESS_PG; +	} +	return SIM_ACCESS_MIN; +} + +void LLAgentAccess::setMaturity(char text) +{ +	mAccess = LLAgentAccess::convertTextToMaturity(text); +} + +void LLAgentAccess::setTransition() +{ +	mAOTransition = true; +} + +bool LLAgentAccess::isInTransition() const +{ +	return mAOTransition; +} + diff --git a/indra/newview/llagentaccess.h b/indra/newview/llagentaccess.h new file mode 100644 index 0000000000..dec0d76cc9 --- /dev/null +++ b/indra/newview/llagentaccess.h @@ -0,0 +1,69 @@ +/**  + * @file llagentaccess.h + * @brief LLAgentAccess class implementation - manages maturity and godmode info + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * Copyright (c) 2001-2009, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#ifndef LL_LLAGENTACCESS_H +#define LL_LLAGENTACCESS_H + +#include "stdtypes.h" + +// forward declaration so that we don't have to include the whole class +class LLControlGroupReader; + +class LLAgentAccess +{ +public: +	LLAgentAccess(LLControlGroupReader& savedSettings); +	 +	bool getAdminOverride() const; +	void setAdminOverride(bool b); + +	void setGodLevel(U8 god_level); +	bool isGodlike() const; +	U8 getGodLevel() const; +	 +	 +	// rather than just expose the preference setting, we're going to actually +	// expose what the client code cares about -- what the user should see +	// based on a combination of the is* and prefers* flags, combined with God bit. +	bool wantsPGOnly() const; +	bool canAccessMature() const; +	bool canAccessAdult() const; +	bool prefersPG() const; +	bool prefersMature() const; +	bool prefersAdult() const; +	bool isTeen() const; +	bool isMature() const; +	bool isAdult() const; +	 +	void setTeen(bool teen); +	void setMaturity(char text); +	 +	static int convertTextToMaturity(char text); +	 +	void setTransition();	// sets the transition bit, which defaults to false +	bool isInTransition() const; +	 +private: +	U8 mAccess;	// SIM_ACCESS_MATURE etc +	U8 mGodLevel; +	bool mAdminOverride; +	 +	// this should be deleted after the 60-day AO transition. +	// It should be safe to remove it in Viewer 2009 +	// It's set by a special short-term flag in login.cgi  +	// called ao_transition. When that's gone, this can go, along with +	// all of the code that depends on it. +	bool mAOTransition; +	 +	// we want this to be const but the getters for it aren't, so we're  +	// overriding it for now +	/* const */ LLControlGroupReader& mSavedSettings; +}; + +#endif // LL_LLAGENTACCESS_H diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index ff63aa1837..8e2d44911c 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -529,6 +529,12 @@ void LLFloaterBuyLandUI::updateCovenantInfo()  		region_name->setText(region->getName());  	} +	LLTextBox* region_type = getChild<LLTextBox>("region_type_text"); +	if (region_type) +	{ +		region_type->setText(region->getSimProductName()); +	} +	  	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");  	if (resellable_clause)  	{ diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index e0396e070c..dc18369bb6 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -41,6 +41,7 @@  #include "llfocusmgr.h"  #include "llparcel.h"  #include "message.h" +#include "lluserauth.h"  #include "llagent.h"  #include "llfloateravatarpicker.h" @@ -319,7 +320,9 @@ BOOL LLPanelLandGeneral::postBuild()  	mTextSalePending = getChild<LLTextBox>("SalePending");  	mTextOwnerLabel = getChild<LLTextBox>("Owner:");  	mTextOwner = getChild<LLTextBox>("OwnerText"); - +	 +	mContentRating = getChild<LLTextBox>("ContentRatingText"); +	mLandType = getChild<LLTextBox>("LandTypeText");  	mBtnProfile = getChild<LLButton>("Profile...");  	mBtnProfile->setClickedCallback(onClickProfile, this); @@ -445,6 +448,8 @@ void LLPanelLandGeneral::refresh()  		mCheckContributeWithDeed->setEnabled(FALSE);  		mTextOwner->setText(LLStringUtil::null); +		mContentRating->setText(LLStringUtil::null); +		mLandType->setText(LLStringUtil::null);  		mBtnProfile->setLabel(getString("profile_text"));  		mBtnProfile->setEnabled(FALSE); @@ -479,6 +484,12 @@ void LLPanelLandGeneral::refresh()  		{  			region_xfer = TRUE;  		} +		 +		if (regionp) +		{ +			mContentRating->setText(regionp->getSimAccessString()); +			mLandType->setText(regionp->getSimProductName()); +		}  		// estate owner/manager cannot edit other parts of the parcel  		BOOL estate_manager_sellable = !parcel->getAuctionID() @@ -1768,8 +1779,7 @@ BOOL LLPanelLandOptions::postBuild()  	mPublishHelpButton = getChild<LLButton>("?");  	mPublishHelpButton->setClickedCallback(onClickPublishHelp, this); - -	if (gAgent.isTeen()) +	if (gAgent.wantsPGOnly())  	{  		// Disable these buttons if they are PG (Teen) users  		mPublishHelpButton->setVisible(FALSE); @@ -1777,26 +1787,14 @@ BOOL LLPanelLandOptions::postBuild()  		mMatureCtrl->setVisible(FALSE);  		mMatureCtrl->setEnabled(FALSE);  	} - -		// Load up the category list -	//now in xml file -	/* -	S32 i; -	for (i = 0; i < LLParcel::C_COUNT; i++) +	 +	if (!gAgent.getAgentAccess().isInTransition())  	{ -		LLParcel::ECategory cat = (LLParcel::ECategory)i; - -		// Selecting Linden Location when you're not a god -		// is also blocked on the server. -		BOOL enabled = TRUE; -		if (!gAgent.isGodlike() -			&& i == LLParcel::C_LINDEN)  -		{ -			enabled = FALSE; -		} - -		mCategoryCombo->add( LLParcel::getCategoryUIString(cat), ADD_BOTTOM, enabled ); -	}*/ +		// remove category for adult if we're post-transition +		// (this code can go away, and the category can be removed from the xml, +		// once we've completed the transition period for adult) +		mCategoryCombo->remove(getString("adult_land_category_label")); +	}	  	mSnapshotCtrl = getChild<LLTextureCtrl>("snapshot_ctrl"); @@ -1969,11 +1967,9 @@ void LLPanelLandOptions::refresh()  		mSetBtn->setEnabled( can_change_landing_point );  		mClearBtn->setEnabled( can_change_landing_point ); -		mMatureCtrl->set(parcel->getMaturePublish()); -		mMatureCtrl->setEnabled( can_change_identity );  		mPublishHelpButton->setEnabled( can_change_identity ); -		if (gAgent.isTeen()) +		if (gAgent.wantsPGOnly())  		{  			// Disable these buttons if they are PG (Teen) users  			mPublishHelpButton->setVisible(FALSE); @@ -1981,6 +1977,34 @@ void LLPanelLandOptions::refresh()  			mMatureCtrl->setVisible(FALSE);  			mMatureCtrl->setEnabled(FALSE);  		} +		else +		{ +			// not teen so fill in the data for the maturity control +			mMatureCtrl->setVisible(TRUE); +			mMatureCtrl->setLabel(getString("mature_check_mature")); +			// they can see the checkbox, but its disposition depends on the  +			// state of the region +			LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion(); +			if (regionp) +			{ +				if (regionp->getSimAccess() == SIM_ACCESS_PG) +				{ +					mMatureCtrl->setEnabled(FALSE); +					mMatureCtrl->set(FALSE); +				} +				else if (regionp->getSimAccess() == SIM_ACCESS_MATURE) +				{ +					mMatureCtrl->setEnabled(can_change_identity); +					mMatureCtrl->set(parcel->getMaturePublish()); +				} +				else if (regionp->getSimAccess() == SIM_ACCESS_ADULT) +				{ +					mMatureCtrl->setEnabled(FALSE); +					mMatureCtrl->set(TRUE); +					mMatureCtrl->setLabel(getString("mature_check_adult")); +				} +			} +		}  	}  } @@ -2749,6 +2773,18 @@ void LLPanelLandCovenant::refresh()  		region_name->setText(region->getName());  	} +	LLTextBox* region_landtype = getChild<LLTextBox>("region_landtype_text"); +	if (region_landtype) +	{ +		region_landtype->setText(region->getSimProductName()); +	} +	 +	LLTextBox* region_maturity = getChild<LLTextBox>("region_maturity_text"); +	if (region_maturity) +	{ +		region_maturity->setText(region->getSimAccessString()); +	} +	  	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");  	if (resellable_clause)  	{ diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 520ed4147e..4c3de65d71 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -186,6 +186,9 @@ protected:  	LLTextBox*		mTextOwnerLabel;  	LLTextBox*		mTextOwner;  	LLButton*		mBtnProfile; +	 +	LLTextBox*		mContentRating; +	LLTextBox*		mLandType;  	LLTextBox*		mTextGroup;  	LLTextBox*		mTextGroupLabel; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 86bc8221d9..588df7b43b 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -295,6 +295,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  	// extract message  	std::string sim_name; +	std::string sim_type = "(unknown)";  	U32 region_flags;  	U8 agent_limit;  	F32 object_bonus_factor; @@ -315,10 +316,18 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  	msg->getBOOL("RegionInfo", "UseEstateSun", use_estate_sun);  	// actually the "last set" sun hour, not the current sun hour. JC  	msg->getF32("RegionInfo", "SunHour", sun_hour); +	// the only reasonable way to decide if we actually have any data is to +	// check to see if any of these fields have nonzero sizes +	if (msg->getSize("RegionInfo2", "ProductSKU") || +		msg->getSize("RegionInfo2", "ProductName")) +	{ +		msg->getString("RegionInfo2", "ProductName", sim_type); +	}  	// GENERAL PANEL  	panel = tab->getChild<LLPanel>("General");  	panel->childSetValue("region_text", LLSD(sim_name)); +	panel->childSetValue("region_type", LLSD(sim_type));  	panel->childSetValue("version_channel_text", gLastVersionChannel);  	panel->childSetValue("block_terraform_check", (region_flags & REGION_FLAGS_BLOCK_TERRAFORM) ? TRUE : FALSE ); @@ -330,7 +339,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)  	panel->childSetValue("block_parcel_search_check", (region_flags & REGION_FLAGS_BLOCK_PARCEL_SEARCH) ? TRUE : FALSE );  	panel->childSetValue("agent_limit_spin", LLSD((F32)agent_limit) );  	panel->childSetValue("object_bonus_spin", LLSD(object_bonus_factor) ); -	panel->childSetValue("access_combo", LLSD(LLViewerRegion::accessToString(sim_access)) ); +	panel->childSetValue("access_combo", LLSD(sim_access) );   	// detect teen grid for maturity @@ -718,7 +727,7 @@ void LLPanelRegionGeneralInfo::onClickManageTelehub(void* data)  // strings[3] = 'Y' - allow land sale, 'N' - not  // strings[4] = agent limit  // strings[5] = object bonus -// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature) +// strings[6] = sim access (0 = unknown, 13 = PG, 21 = Mature, 42 = Adult)  // strings[7] = restrict pushobject  // strings[8] = 'Y' - allow parcel subdivide, 'N' - not  // strings[9] = 'Y' - block parcel search, 'N' - allow @@ -739,7 +748,7 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate()  		body["prim_bonus"] = childGetValue("object_bonus_spin");  		// the combo box stores strings "Mature" and "PG", but we have to convert back to a number,   		// because the sim doesn't know from strings for this stuff -		body["sim_access"] = LLViewerRegion::stringToAccess(childGetValue("access_combo").asString()); +		body["sim_access"] = childGetValue("access_combo");  		body["restrict_pushobject"] = childGetValue("restrict_pushobject");  		body["allow_parcel_changes"] = childGetValue("allow_parcel_changes_check");  		body["block_parcel_search"] = childGetValue("block_parcel_search_check"); @@ -771,7 +780,7 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate()  		buffer = llformat("%f", value);  		strings.push_back(strings_t::value_type(buffer)); -		U8 access = LLViewerRegion::stringToAccess(childGetValue("access_combo").asString()); +		U8 access = childGetValue("access_combo").asInteger();  		buffer = llformat("%d", (S32)access);  		strings.push_back(strings_t::value_type(buffer)); diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index f6002653ab..2677467611 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -61,7 +61,10 @@ BOOL LLFloaterSettingsDebug::postBuild()  		f(LLComboBox* c) : combo(c) {}  		virtual void apply(const std::string& name, LLControlVariable* control)  		{ -			combo->add(name, (void*)control); +			if (!control->isHiddenFromSettingsEditor()) +			{ +				combo->add(name, (void*)control); +			}  		}  	} func(settings_combo); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index d59f513925..e2e71f51fa 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -429,9 +429,19 @@ void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent  void LLFloaterWorldMap::draw()  {  	// Hide/Show Mature Events controls -	childSetVisible("events_mature_icon", !gAgent.isTeen()); -	childSetVisible("events_mature_label", !gAgent.isTeen()); -	childSetVisible("event_mature_chk", !gAgent.isTeen()); +	childSetVisible("events_mature_icon", gAgent.canAccessMature()); +	childSetVisible("events_mature_label", gAgent.canAccessMature()); +	childSetVisible("event_mature_chk", gAgent.canAccessMature()); + +	childSetVisible("events_adult_icon", gAgent.canAccessMature()); +	childSetVisible("events_adult_label", gAgent.canAccessMature()); +	childSetVisible("event_adult_chk", gAgent.canAccessMature()); +	bool adult_enabled = gAgent.canAccessAdult(); +	if (!adult_enabled) +	{ +		childSetValue("event_adult_chk", FALSE); +	} +	childSetEnabled("event_adult_chk", adult_enabled);  	// On orientation island, users don't have a home location yet, so don't  	// let them teleport "home".  It dumps them in an often-crowed welcome @@ -1315,6 +1325,7 @@ void LLFloaterWorldMap::onCheckEvents(LLUICtrl*, void* data)  	LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;  	if(!self) return;  	self->childSetEnabled("event_mature_chk", self->childGetValue("event_chk")); +	self->childSetEnabled("event_adult_chk", self->childGetValue("event_chk"));  }  // protected diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 0c60357dfb..e6639a2da5 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -223,6 +223,7 @@ void LLPanelClassified::reset()  	mPosGlobal.clearVec();  	clearCtrls(); +	resetDirty();  } @@ -285,7 +286,7 @@ BOOL LLPanelClassified::postBuild()  	mMatureCombo->setCurrentByIndex(0);  	mMatureCombo->setCommitCallback(onCommitAny);  	mMatureCombo->setCallbackUserData(this); -	if (gAgent.isTeen()) +	if (gAgent.wantsPGOnly())  	{  		// Teens don't get to set mature flag. JC  		mMatureCombo->setVisible(FALSE); @@ -308,6 +309,7 @@ BOOL LLPanelClassified::postBuild()  		mClickThroughText = getChild<LLTextBox>("click_through_text");  	} +	resetDirty();      return TRUE;  } @@ -540,7 +542,10 @@ void LLPanelClassified::sendClassifiedInfoUpdate()  	{  		auto_renew = mAutoRenewCheck->get();  	} -	U8 flags = pack_classified_flags(mature, auto_renew); +    // These flags doesn't matter here. +    const bool adult_enabled = false; +	const bool is_pg = false; +	U8 flags = pack_classified_flags_request(auto_renew, is_pg, mature, adult_enabled);  	msg->addU8Fast(_PREHASH_ClassifiedFlags, flags);  	msg->addS32("PriceForListing", mPriceForListing);  	gAgent.sendReliableMessage(); @@ -678,6 +683,7 @@ void LLPanelClassified::processClassifiedInfoReply(LLMessageSystem *msg, void **  		self->resetDirty(); +		// I don't know if a second call is deliberate or a bad merge, so I'm leaving it here.   		self->resetDirty();      }  } diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp index a4013f104c..47ed72aa77 100644 --- a/indra/newview/llpanelplace.cpp +++ b/indra/newview/llpanelplace.cpp @@ -294,9 +294,14 @@ void LLPanelPlace::processParcelInfoReply(LLMessageSystem *msg, void **)  			self->mInfoEditor->setText(info_text);  		} -		// HACK: Flag 0x1 == mature region, otherwise assume PG +		// HACK: Flag 0x2 == adult region, +		// Flag 0x1 == mature region, otherwise assume PG  		std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG); -		if (flags & 0x1) +		if (flags & 0x2) +		{ +			rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT); +		} +		else if (flags & 0x1)  		{  			rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE);  		} diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index cdcd68de38..86f590a0f0 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -89,8 +89,7 @@ BOOL LLProgressView::postBuild()  	getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle())); -	getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage); -	getChild<LLTextBox>("message_text")->setCallbackUserData(this); +	getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this);  	sInstance = this;  	return TRUE; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 5f96fc7da0..bd2e157779 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1361,14 +1361,32 @@ bool idle_startup()  				LLStartUp::deletePasswordFromDisk();  			} -			text = LLUserAuth::getInstance()->getResponse("agent_access"); -			if(!text.empty() && (text[0] == 'M')) +			// this is their actual ability to access content +			text = LLUserAuth::getInstance()->getResponse("agent_access_max"); +			if (!text.empty())  			{ -				gAgent.setTeen(false); +				// agent_access can be 'A', 'M', and 'PG'. +				gAgent.setMaturity(text[0]);  			} -			else +			 +			// this is the value of their preference setting for that content +			// which will always be <= agent_access_max +			text = LLUserAuth::getInstance()->getResponse("agent_region_access"); +			if (!text.empty()) +			{ +				int preferredMaturity = LLAgent::convertTextToMaturity(text[0]); +				gSavedSettings.setU32("PreferredMaturity", preferredMaturity); +			} +			// During the AO transition, this flag will be true. Then the flag will +			// go away. After the AO transition, this code and all the code that +			// uses it can be deleted. +			text = LLUserAuth::getInstance()->getResponse("ao_transition"); +			if (!text.empty())  			{ -				gAgent.setTeen(true); +				if (text == "1") +				{ +					gAgent.setAOTransition(); +				}  			}  			text = LLUserAuth::getInstance()->getResponse("start_location"); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 50e5b4e90c..96a4f74927 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -470,7 +470,6 @@ BOOL enable_grab_texture(void*);  void handle_dump_region_object_cache(void*);  BOOL menu_ui_enabled(void *user_data); -void check_toggle_control( LLUICtrl *, void* user_data );  BOOL menu_check_control( void* user_data);  void menu_toggle_variable( void* user_data );  BOOL menu_check_variable( void* user_data); @@ -1025,6 +1024,11 @@ extern BOOL gDebugSelectMgr;  void init_debug_ui_menu(LLMenuGL* menu)  { +	menu->append(new LLMenuItemCheckGL("Rotate Mini-Map", menu_toggle_control, NULL, menu_check_control, (void*)"MiniMapRotate")); +	menu->append(new LLMenuItemCheckGL("Use default system color picker", menu_toggle_control, NULL, menu_check_control, (void*)"UseDefaultColorPicker")); +	menu->append(new LLMenuItemCheckGL("Show search panel in overlay bar", menu_toggle_control, NULL, menu_check_control, (void*)"ShowSearchBar")); +	menu->appendSeparator(); +  	menu->append(new LLMenuItemCallGL("Web Browser Test", &handle_web_browser_test));  	menu->append(new LLMenuItemCallGL("Buy Currency Test", &handle_buy_currency_test));  	menu->append(new LLMenuItemCallGL("Editable UI", &edit_ui)); @@ -6182,13 +6186,6 @@ class LLToggleControl : public view_listener_t  	}  }; -// As above, but can be a callback from a LLCheckboxCtrl -void check_toggle_control( LLUICtrl *, void* user_data ) -{ -	BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) ); -	gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked ); -} -  BOOL menu_check_control( void* user_data)  {  	return gSavedSettings.getBOOL((char*)user_data); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index a82e4a9a4d..e9fedf37d8 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -80,7 +80,6 @@ BOOL is_agent_friend(const LLUUID& agent_id);  BOOL is_agent_mappable(const LLUUID& agent_id);  void menu_toggle_control( void* user_data ); -void check_toggle_control( LLUICtrl *, void* user_data );  void confirm_replace_attachment(S32 option, void* user_data);  void handle_detach_from_avatar(void* user_data);  void attach_label(std::string& label, void* user_data); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index dae3529319..6ffb19bcdf 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4118,29 +4118,158 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )  	}  } -void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data) +bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)  { -	std::string buffer; -	msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer); -	BOOL modal = FALSE; -	msgsystem->getBOOL("AlertData", "Modal", modal); -	process_alert_core(buffer, modal); +	S32 option = LLNotification::getSelectedOption(notification, response); +	 +	if (0 == option) +	{ +		// set the preference to the maturity of the region we're calling +		int preferredMaturity = notification["payload"]["_region_access"].asInteger(); +		gSavedSettings.setU32("PreferredMaturity", preferredMaturity); +		gAgent.sendMaturityPreferenceToServer(preferredMaturity); + +	} +	 +	return false;  } -void process_alert_message(LLMessageSystem *msgsystem, void **user_data) +// some of the server notifications need special handling. This is where we do that. +bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)  { -	std::string buffer; -	msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer); -	BOOL modal = FALSE; -	process_alert_core(buffer, modal); +	int regionAccess = llsdBlock["_region_access"].asInteger(); +	llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess); +	 +	// we're going to throw the LLSD in there in case anyone ever wants to use it +	LLNotifications::instance().add(notificationID+"_Notify", llsdBlock); +	 +	if (regionAccess == SIM_ACCESS_MATURE) +	{ +		if (gAgent.isTeen()) +		{ +			LLNotifications::instance().add(notificationID+"_KB", llsdBlock); +			return true; +		} +		else if (gAgent.prefersPG()) +		{ +			LLNotifications::instance().add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); +			return true; +		} +	} +	else if (regionAccess == SIM_ACCESS_ADULT) +	{ +		if (!gAgent.isAdult()) +		{ +			LLNotifications::instance().add(notificationID+"_KB", llsdBlock); +			return true; +		} +		else if (gAgent.prefersPG() || gAgent.prefersMature()) +		{ +			LLNotifications::instance().add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); +			return true; +		} +	} +	return false;  } -void process_alert_core(const std::string& message, BOOL modal) +bool attempt_standard_notification(LLMessageSystem* msgsystem) +{ +	// if we have additional alert data +	if (msgsystem->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0) +	{ +		// notification was specified using the new mechanism, so we can just handle it here +		std::string notificationID; +		std::string llsdRaw; +		LLSD llsdBlock; +		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID); +		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsdRaw); +		if (llsdRaw.length()) +		{ +			std::istringstream llsdData(llsdRaw); +			if (!LLSDSerialize::deserialize(llsdBlock, llsdData, llsdRaw.length())) +			{ +				llwarns << "attempt_standard_notification: Attempted to read notification parameter data into LLSD but failed:" << llsdRaw << llendl; +			} +		} +		 +		if ( +			(notificationID == "RegionEntryAccessBlocked") || +			(notificationID == "LandClaimAccessBlocked") || +			(notificationID == "LandBuyAccessBlocked") +		   ) +		{ +			/*--------------------------------------------------------------------- +			 (Commented so a grep will find the notification strings, since +			 we construct them on the fly; if you add additional notifications, +			 please update the comment.) +			  +			 Could throw any of the following notifications: +			  +				RegionEntryAccessBlocked +				RegionEntryAccessBlocked_Notify +				RegionEntryAccessBlocked_Change +				RegionEntryAccessBlocked_KB +				LandClaimAccessBlocked  +				LandClaimAccessBlocked_Notify  +				LandClaimAccessBlocked_Change  +				LandClaimAccessBlocked_KB  +				LandBuyAccessBlocked +				LandBuyAccessBlocked_Notify +				LandBuyAccessBlocked_Change +				LandBuyAccessBlocked_KB +			  +			-----------------------------------------------------------------------*/  +			if (handle_special_notification(notificationID, llsdBlock)) +			{ +				return true; +			} +		} +		 +		LLNotifications::instance().add(notificationID, llsdBlock); +		return true; +	}	 +	return false; +} + + +void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data) +{ +	// make sure the cursor is back to the usual default since the +	// alert is probably due to some kind of error. +	gViewerWindow->getWindow()->resetBusyCount(); +	 +	if (!attempt_standard_notification(msgsystem)) +	{ +		BOOL modal = FALSE; +		msgsystem->getBOOL("AlertData", "Modal", modal); +		std::string buffer; +		msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer); +		process_alert_core(buffer, modal); +	} +} + +// The only difference between this routine and the previous is the fact that +// for this routine, the modal parameter is always false. Sadly, for the message +// handled by this routine, there is no "Modal" parameter on the message, and +// there's no API to tell if a message has the given parameter or not. +// So we can't handle the messages with the same handler. +void process_alert_message(LLMessageSystem *msgsystem, void **user_data)  {  	// make sure the cursor is back to the usual default since the  	// alert is probably due to some kind of error.  	gViewerWindow->getWindow()->resetBusyCount(); +		 +	if (!attempt_standard_notification(msgsystem)) +	{ +		BOOL modal = FALSE; +		std::string buffer; +		msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer); +		process_alert_core(buffer, modal); +	} +} +void process_alert_core(const std::string& message, BOOL modal) +{  	// HACK -- handle callbacks for specific alerts  	if ( message == "You died and have been teleported to your home location")  	{ @@ -4732,17 +4861,63 @@ std::string formatted_time(const time_t& the_time)  void process_teleport_failed(LLMessageSystem *msg, void**)  {  	std::string reason; -	msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason); - +	std::string big_reason;  	LLSD args; -	std::string big_reason = LLAgent::sTeleportErrorMessages[reason]; -	if ( big_reason.size() > 0 ) -	{	// Substitute verbose reason from the local map -		args["REASON"] = big_reason; + +	// if we have additional alert data +	if (msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0) +	{ +		// Get the message ID +		msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, reason); +		big_reason = LLAgent::sTeleportErrorMessages[reason]; +		if ( big_reason.size() > 0 ) +		{	// Substitute verbose reason from the local map +			args["REASON"] = big_reason; +		} +		else +		{	// Nothing found in the map - use what the server returned in the original message block +			msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason); +			args["REASON"] = reason; +		} + +		LLSD llsd_block; +		std::string llsd_raw; +		msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsd_raw); +		if (llsd_raw.length()) +		{ +			std::istringstream llsd_data(llsd_raw); +			if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length())) +			{ +				llwarns << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << llendl; +			} +			else +			{ +				// change notification name in this special case +				if (handle_special_notification("RegionEntryAccessBlocked", llsd_block)) +				{ +					if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) +					{ +						gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); +					} +					return; +				} +			} +		} +  	}  	else -	{	// Nothing found in the map - use what the server returned -		args["REASON"] = reason; +	{ +		msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason); + +		big_reason = LLAgent::sTeleportErrorMessages[reason]; +		if ( big_reason.size() > 0 ) +		{	// Substitute verbose reason from the local map +			args["REASON"] = big_reason; +		} +		else +		{	// Nothing found in the map - use what the server returned +			args["REASON"] = reason; +		}  	}  	LLNotifications::instance().add("CouldNotTeleportReason", args); diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index bf40ccce49..e7a4303a8e 100644 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -107,6 +107,7 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/);  void process_money_balance_reply(LLMessageSystem* msg_system, void**);  void process_adjust_balance(LLMessageSystem* msg_system, void**); +bool attempt_standard_notification(LLMessageSystem* msg);  void process_alert_message(LLMessageSystem* msg, void**);  void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data);  void process_alert_core(const std::string& message, BOOL modal); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 87b6652056..750151ea2d 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -56,6 +56,7 @@  #include "llhttpnode.h"  #include "llsdutil.h"  #include "llstartup.h" +#include "lltrans.h"  #include "llviewerobjectlist.h"  #include "llviewerparceloverlay.h"  #include "llvlmanager.h" @@ -162,6 +163,11 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	mSimAccess( SIM_ACCESS_MIN ),  	mBillableFactor(1.0),  	mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT), +	mClassID(0), +	mCPURatio(0), +	mColoName("unknown"), +	mProductSKU("unknown"), +	mProductName("unknown"),  	mCacheLoaded(FALSE),  	mCacheEntriesCount(0),  	mCacheID(), @@ -539,56 +545,30 @@ std::string LLViewerRegion::regionFlagsToString(U32 flags)  	return result;  } -// *TODO:Translate -const char* SIM_ACCESS_STR[] = { "Free Trial", -						   "PG", -						   "Mature", -						   "Offline", -						   "Unknown" }; -							  // static  std::string LLViewerRegion::accessToString(U8 sim_access)  {  	switch(sim_access)  	{ -	case SIM_ACCESS_TRIAL: -		return SIM_ACCESS_STR[0]; -  	case SIM_ACCESS_PG: -		return SIM_ACCESS_STR[1]; +		return LLTrans::getString("SIM_ACCESS_PG");  	case SIM_ACCESS_MATURE: -		return SIM_ACCESS_STR[2]; +		return LLTrans::getString("SIM_ACCESS_MATURE"); + +	case SIM_ACCESS_ADULT: +		return LLTrans::getString("SIM_ACCESS_ADULT");  	case SIM_ACCESS_DOWN: -		return SIM_ACCESS_STR[3]; +		return LLTrans::getString("SIM_ACCESS_DOWN");  	case SIM_ACCESS_MIN:  	default: -		return SIM_ACCESS_STR[4]; +		return LLTrans::getString("SIM_ACCESS_MIN");  	}  }  // static -U8 LLViewerRegion::stringToAccess(const std::string& access_str) -{ -	U8 sim_access = SIM_ACCESS_MIN; -	if (access_str == SIM_ACCESS_STR[0]) -	{ -		sim_access = SIM_ACCESS_TRIAL; -	} -	else if (access_str == SIM_ACCESS_STR[1]) -	{ -		sim_access = SIM_ACCESS_PG; -	} -	else if (access_str == SIM_ACCESS_STR[2]) -	{ -		sim_access = SIM_ACCESS_MATURE; -	} -	return sim_access; -} - -// static  std::string LLViewerRegion::accessToShortString(U8 sim_access)  {  	switch(sim_access)		/* Flawfinder: ignore */ @@ -596,12 +576,12 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access)  	case SIM_ACCESS_PG:  		return "PG"; -	case SIM_ACCESS_TRIAL: -		return "TR"; -  	case SIM_ACCESS_MATURE:  		return "M"; +	case SIM_ACCESS_ADULT: +		return "A"; +  	case SIM_ACCESS_MIN:  	default:  		return "U"; @@ -1315,6 +1295,32 @@ void LLViewerRegion::unpackRegionHandshake()  	LLUUID region_id;  	msg->getUUID("RegionInfo2", "RegionID", region_id);  	setRegionID(region_id); +	 +	// Retrieve the CR-53 (Homestead/Land SKU) information +	S32 classID = 0; +	S32 cpuRatio = 0; +	std::string coloName; +	std::string productSKU; +	std::string productName; + +	// the only reasonable way to decide if we actually have any data is to +	// check to see if any of these fields have nonzero sizes +	if (msg->getSize("RegionInfo3", "ColoName") || +	    msg->getSize("RegionInfo3", "ProductSKU") || +	    msg->getSize("RegionInfo3", "ProductName")) +	{ +		msg->getS32     ("RegionInfo3", "CPUClassID",  classID); +		msg->getS32     ("RegionInfo3", "CPURatio",    cpuRatio); +		msg->getString  ("RegionInfo3", "ColoName",    coloName); +		msg->getString  ("RegionInfo3", "ProductSKU",  productSKU); +		msg->getString  ("RegionInfo3", "ProductName", productName); +		 +		mClassID = classID; +		mCPURatio = cpuRatio; +		mColoName = coloName; +		mProductSKU = productSKU; +		mProductName = productName; +	}  	LLVLComposition *compp = getComposition();  	if (compp) @@ -1420,6 +1426,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	capabilityNames.append("ServerReleaseNotes");  	capabilityNames.append("StartGroupProposal");  	capabilityNames.append("UntrustedSimulatorMessage"); +	capabilityNames.append("UpdateAgentInformation");  	capabilityNames.append("UpdateAgentLanguage");  	capabilityNames.append("UpdateGestureAgentInventory");  	capabilityNames.append("UpdateNotecardAgentInventory"); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 6b71ea07bb..b0a98a99b8 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -182,18 +182,24 @@ public:  	void setSimAccess(U8 sim_access)			{ mSimAccess = sim_access; }  	U8 getSimAccess() const						{ return mSimAccess; }  	const std::string getSimAccessString() const; +	 +	// Homestead-related getters; there are no setters as nobody should be +	// setting them other than the individual message handler which is a member +	S32 getSimClassID()                    const { return mClassID; } +	S32 getSimCPURatio()                   const { return mCPURatio; } +	const std::string& getSimColoName()    const { return mColoName; } +	const std::string& getSimProductSKU()  const { return mProductSKU; } +	const std::string& getSimProductName() const { return mProductName; }  	// Returns "Sandbox", "Expensive", etc.  	static std::string regionFlagsToString(U32 flags); -	// Returns "Mature", "PG", etc. +	// Returns translated version of "Mature", "PG", "Adult", etc.  	static std::string accessToString(U8 sim_access); -	static U8 stringToAccess(const std::string& access_str); - -	// Returns "M", "PG", etc. +	// Returns "M", "PG", "A" etc.  	static std::string accessToShortString(U8 sim_access); - +	  	// helper function which just makes sure all interested parties  	// can process the message.  	static void processRegionInfo(LLMessageSystem* msg, void**); @@ -357,6 +363,14 @@ private:  	U32		mMaxTasks;				// max prim count  	F32		mCameraDistanceSquared;	// updated once per frame +	// Information for Homestead / CR-53 +	S32 mClassID; +	S32 mCPURatio; +	std::string mColoName; +	std::string mProductSKU; +	std::string mProductName; +	 +	  	// Maps local ids to cache entries.  	// Regions can have order 10,000 objects, so assume  	// a structure of size 2^14 = 16,000 diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 44d9a72868..71406d268d 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2450,9 +2450,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)  		}  	} -	// Debugging view for unified notifications +	// Debugging view for unified notifications -- we need Ctrl+Shift+Alt to get it  +	// since Ctrl+Shift maps to Nighttime under windlight.  	if ((MASK_SHIFT & mask)   		&& (MASK_CONTROL & mask) +		&& (MASK_ALT & mask)  		&& ('N' == key || 'n' == key))  	{  		LLFloaterNotificationConsole::showInstance(); diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index c9a3bd2112..572f31f566 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -186,6 +186,7 @@ void LLWorldMap::eraseItems()  		mInfohubs.clear();  		mPGEvents.clear();  		mMatureEvents.clear(); +		mAdultEvents.clear();  		mLandForSale.clear();  	}  // 	mAgentLocationsMap.clear(); // persists @@ -311,11 +312,23 @@ void LLWorldMap::setCurrentLayer(S32 layer, bool request_layer)  		sendItemRequest(MAP_ITEM_MATURE_EVENT);  	} +	if (mAdultEvents.size() == 0) +	{ +		// Request for events (adult) +		sendItemRequest(MAP_ITEM_ADULT_EVENT); +	} +  	if (mLandForSale.size() == 0)  	{  		// Request for Land For Sale  		sendItemRequest(MAP_ITEM_LAND_FOR_SALE);  	} +	 +	if (mLandForSaleAdult.size() == 0) +	{ +		// Request for Land For Sale +		sendItemRequest(MAP_ITEM_LAND_FOR_SALE_ADULT); +	}  	clearImageRefs();  	clearSimFlags(); @@ -742,6 +755,7 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**)  			}  			case MAP_ITEM_PG_EVENT: // events  			case MAP_ITEM_MATURE_EVENT: +			case MAP_ITEM_ADULT_EVENT:  			{  				struct tm* timep;  				// Convert to Pacific, based on server's opinion of whether @@ -762,16 +776,29 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**)  				{  					LLWorldMap::getInstance()->mPGEvents.push_back(new_item);  				} -				else +				else if (type == MAP_ITEM_MATURE_EVENT)  				{  					LLWorldMap::getInstance()->mMatureEvents.push_back(new_item);  				} +				else if (type == MAP_ITEM_ADULT_EVENT) +				{ +					LLWorldMap::getInstance()->mAdultEvents.push_back(new_item); +				} +  				break;  			}  			case MAP_ITEM_LAND_FOR_SALE: // land for sale +			case MAP_ITEM_LAND_FOR_SALE_ADULT: // adult land for sale   			{  				new_item.mToolTip = llformat("%d sq. m. L$%d", new_item.mExtra, new_item.mExtra2); -				LLWorldMap::getInstance()->mLandForSale.push_back(new_item); +				if (type == MAP_ITEM_LAND_FOR_SALE) +				{ +					LLWorldMap::getInstance()->mLandForSale.push_back(new_item); +				} +				else if (type == MAP_ITEM_LAND_FOR_SALE_ADULT) +				{ +					LLWorldMap::getInstance()->mLandForSaleAdult.push_back(new_item); +				}  				break;  			}  			case MAP_ITEM_CLASSIFIED: // classifieds diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index 423af6a289..6ce66ffab0 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -192,7 +192,9 @@ public:  	item_info_list_t mInfohubs;  	item_info_list_t mPGEvents;  	item_info_list_t mMatureEvents; +	item_info_list_t mAdultEvents;  	item_info_list_t mLandForSale; +	item_info_list_t mLandForSaleAdult;  	std::map<U64,S32> mNumAgents; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 9ff94751d0..7f8f4cc026 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -83,12 +83,14 @@ LLUIImagePtr LLWorldMapView::sInfohubImage = NULL;  LLUIImagePtr LLWorldMapView::sHomeImage = NULL;  LLUIImagePtr LLWorldMapView::sEventImage = NULL;  LLUIImagePtr LLWorldMapView::sEventMatureImage = NULL; +LLUIImagePtr LLWorldMapView::sEventAdultImage = NULL;  LLUIImagePtr LLWorldMapView::sTrackCircleImage = NULL;  LLUIImagePtr LLWorldMapView::sTrackArrowImage = NULL;  LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL;  LLUIImagePtr LLWorldMapView::sForSaleImage = NULL; +LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL;  F32 LLWorldMapView::sThresholdA = 48.f;  F32 LLWorldMapView::sThresholdB = 96.f; @@ -125,11 +127,15 @@ void LLWorldMapView::initClass()  	sInfohubImage = 		LLUI::getUIImage("map_infohub.tga");  	sEventImage =			LLUI::getUIImage("map_event.tga");  	sEventMatureImage =		LLUI::getUIImage("map_event_mature.tga"); +	// To Do: update the image resource for adult events. +	sEventAdultImage =		LLUI::getUIImage("map_event_adult.tga");  	sTrackCircleImage =		LLUI::getUIImage("map_track_16.tga");  	sTrackArrowImage =		LLUI::getUIImage("direction_arrow.tga");  	sClassifiedsImage =		LLUI::getUIImage("icon_top_pick.tga");  	sForSaleImage =			LLUI::getUIImage("icon_for_sale.tga"); +	// To Do: update the image resource for adult lands on sale. +	sForSaleAdultImage =    LLUI::getUIImage("icon_for_sale_adult.tga");  	sStringsMap["loading"] = LLTrans::getString("texture_loading");  	sStringsMap["offline"] = LLTrans::getString("worldmap_offline"); @@ -149,11 +155,13 @@ void LLWorldMapView::cleanupClass()  	sHomeImage = NULL;  	sEventImage = NULL;  	sEventMatureImage = NULL; +	sEventAdultImage = NULL;  	sTrackCircleImage = NULL;  	sTrackArrowImage = NULL;  	sClassifiedsImage = NULL;  	sForSaleImage = NULL; +	sForSaleAdultImage = NULL;  }  LLWorldMapView::LLWorldMapView(const std::string& name, const LLRect& rect ) @@ -332,12 +340,11 @@ void LLWorldMapView::draw()  		}  		LLWorldMapLayer *layer = &LLWorldMap::getInstance()->mMapLayers[LLWorldMap::getInstance()->mCurrentMap][layer_idx];  		LLViewerImage *current_image = layer->LayerImage; -#if 1 || LL_RELEASE_FOR_DOWNLOAD +  		if (current_image->isMissingAsset())  		{  			continue; // better to draw nothing than the missing asset image  		} -#endif  		LLVector3d origin_global((F64)layer->LayerExtents.mLeft * REGION_WIDTH_METERS, (F64)layer->LayerExtents.mBottom * REGION_WIDTH_METERS, 0.f); @@ -419,7 +426,7 @@ void LLWorldMapView::draw()  	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  	gGL.setColorMask(true, true); -#if 1 +	// there used to be an #if 1 here, but it was uncommented; perhaps marking a block of code?  	F32 sim_alpha = 1.f;  	// Draw one image per region, centered on the camera position. @@ -633,7 +640,11 @@ void LLWorldMapView::draw()  			gGL.end();  		} -		// If this is mature, and you are not, draw a line across it +		// As part of the AO project, we no longer want to draw access indicators; +		// it's too complicated to get all the rules straight and will only  +		// cause confusion. +		/********************** +		 // If this is mature, and you are not, draw a line across it  		if (info->mAccess != SIM_ACCESS_DOWN  			&& info->mAccess > SIM_ACCESS_PG  			&& gAgent.isTeen()) @@ -649,6 +660,7 @@ void LLWorldMapView::draw()  				gGL.vertex2f(right, top);  			gGL.end();  		} +		 **********************/  		// Draw the region name in the lower left corner  		LLFontGL* font = LLFontGL::getFontSansSerifSmall(); @@ -705,10 +717,10 @@ void LLWorldMapView::draw()  			}  		}  	} -#endif +	// #endif used to be here -#if 1 +	// there used to be an #if 1 here, but it was uncommented; perhaps marking a block of code?  	// Draw background rectangle  	LLGLSUIDefault gls_ui;  	{ @@ -744,8 +756,15 @@ void LLWorldMapView::draw()  	if (gSavedSettings.getBOOL("MapShowLandForSale"))  	{  		drawGenericItems(LLWorldMap::getInstance()->mLandForSale, sForSaleImage); +		// for 1.23, we're showing normal land and adult land in the same UI; you don't +		// get a choice about which ones you want. If you're currently asking for adult +		// content and land you'll get the adult land. +		if (gAgent.canAccessAdult()) +		{ +			drawGenericItems(LLWorldMap::getInstance()->mLandForSaleAdult, sForSaleAdultImage); +		}  	} - +	  	if (gSavedSettings.getBOOL("MapShowEvents"))  	{  		drawEvents(); @@ -809,7 +828,7 @@ void LLWorldMapView::draw()  			drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, "Loading...", "");  		}  	} -#endif +	// #endif used to be here  	// turn off the scissor  	LLGLDisable no_scissor(GL_SCISSOR_TEST); @@ -943,7 +962,11 @@ void LLWorldMapView::drawAgents()  void LLWorldMapView::drawEvents()  { -    BOOL show_mature = gSavedSettings.getBOOL("ShowMatureEvents"); +	bool mature_enabled = gAgent.canAccessMature(); +	bool adult_enabled = gAgent.canAccessAdult(); + +    BOOL show_mature = mature_enabled && gSavedSettings.getBOOL("ShowMatureEvents"); +	BOOL show_adult = adult_enabled && gSavedSettings.getBOOL("ShowAdultEvents");      // First the non-selected events      LLWorldMap::item_info_list_t::const_iterator e; @@ -964,7 +987,16 @@ void LLWorldMapView::drawEvents()              }          }      } - +	if (show_adult) +    { +        for (e = LLWorldMap::getInstance()->mAdultEvents.begin(); e != LLWorldMap::getInstance()->mAdultEvents.end(); ++e) +        { +            if (!e->mSelected) +            { +                drawGenericItem(*e, sEventAdultImage);        +            } +        } +    }      // Then the selected events      for (e = LLWorldMap::getInstance()->mPGEvents.begin(); e != LLWorldMap::getInstance()->mPGEvents.end(); ++e)      { @@ -983,6 +1015,16 @@ void LLWorldMapView::drawEvents()              }          }      } +	if (show_adult) +    { +        for (e = LLWorldMap::getInstance()->mAdultEvents.begin(); e != LLWorldMap::getInstance()->mAdultEvents.end(); ++e) +        { +            if (e->mSelected) +            { +                drawGenericItem(*e, sEventAdultImage);        +            } +        } +    }  } @@ -1572,6 +1614,10 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,  	{  		(*it).mSelected = FALSE;  	} +	for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it) +	{ +		(*it).mSelected = FALSE; +	}  	for (it = LLWorldMap::getInstance()->mLandForSale.begin(); it != LLWorldMap::getInstance()->mLandForSale.end(); ++it)  	{  		(*it).mSelected = FALSE; @@ -1607,6 +1653,21 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,  				}  			}  		} +		if (gSavedSettings.getBOOL("ShowAdultEvents")) +		{ +			for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it) +			{ +				LLItemInfo& event = *it; + +				if (checkItemHit(x, y, event, id, false)) +				{ +					*hit_type = MAP_ITEM_ADULT_EVENT; +					mItemPicked = TRUE; +					gFloaterWorldMap->trackEvent(event); +					return; +				} +			} +		}  	}  	if (gSavedSettings.getBOOL("MapShowLandForSale")) @@ -1622,8 +1683,19 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,  				return;  			}  		} -	} +		 +		for (it = LLWorldMap::getInstance()->mLandForSaleAdult.begin(); it != LLWorldMap::getInstance()->mLandForSaleAdult.end(); ++it) +		{ +			LLItemInfo& land = *it; +			if (checkItemHit(x, y, land, id, true)) +			{ +				*hit_type = MAP_ITEM_LAND_FOR_SALE_ADULT; +				mItemPicked = TRUE; +				return; +			} +		} +	}  	// If we get here, we haven't clicked on an icon  	gFloaterWorldMap->trackLocation(pos_global); @@ -1803,6 +1875,7 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )  		{  		case MAP_ITEM_PG_EVENT:  		case MAP_ITEM_MATURE_EVENT: +		case MAP_ITEM_ADULT_EVENT:  			{  				gFloaterWorldMap->close();  				// This is an ungainly hack @@ -1815,6 +1888,7 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )  				break;  			}  		case MAP_ITEM_LAND_FOR_SALE: +		case MAP_ITEM_LAND_FOR_SALE_ADULT:  			{  				gFloaterWorldMap->close();  				LLFloaterDirectory::showLandForSale(id); diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index 980ddf9c73..1717b76beb 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -148,10 +148,12 @@ public:  	static LLUIImagePtr	sHomeImage;  	static LLUIImagePtr	sEventImage;  	static LLUIImagePtr	sEventMatureImage; +	static LLUIImagePtr	sEventAdultImage;  	static LLUIImagePtr	sTrackCircleImage;  	static LLUIImagePtr	sTrackArrowImage;  	static LLUIImagePtr	sClassifiedsImage;  	static LLUIImagePtr	sForSaleImage; +	static LLUIImagePtr	sForSaleAdultImage;  	static F32		sThresholdA;  	static F32		sThresholdB; diff --git a/indra/newview/skins/default/textures/icon_event_adult.tga b/indra/newview/skins/default/textures/icon_event_adult.tga Binary files differnew file mode 100644 index 0000000000..c344fb1e78 --- /dev/null +++ b/indra/newview/skins/default/textures/icon_event_adult.tga diff --git a/indra/newview/skins/default/textures/icon_for_sale_adult.tga b/indra/newview/skins/default/textures/icon_for_sale_adult.tga Binary files differnew file mode 100644 index 0000000000..6a99188f87 --- /dev/null +++ b/indra/newview/skins/default/textures/icon_for_sale_adult.tga diff --git a/indra/newview/skins/default/textures/map_event_adult.tga b/indra/newview/skins/default/textures/map_event_adult.tga Binary files differnew file mode 100644 index 0000000000..c344fb1e78 --- /dev/null +++ b/indra/newview/skins/default/textures/map_event_adult.tga diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp new file mode 100644 index 0000000000..fc18f10e7d --- /dev/null +++ b/indra/newview/tests/llagentaccess_test.cpp @@ -0,0 +1,234 @@ +/**  + * @file llagentaccess_test.cpp + * @brief LLAgentAccess tests + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * Copyright (c) 2001-2009, Linden Research, Inc. + * $/LicenseInfo$ + */ +#include "../test/lltut.h" + +#include "../llagentaccess.h" + +#include "llcontrolgroupreader.h" +#include "indra_constants.h" + +#include <iostream> + +class LLControlGroupReader_Test : public LLControlGroupReader +{ +public: +	LLControlGroupReader_Test() : test_preferred_maturity(SIM_ACCESS_PG) {} +	 +	virtual std::string getString(const std::string& name) +	{ +		return ""; +	} +	virtual std::string	getText(const std::string& name) +	{ +		return ""; +	} +	virtual BOOL getBOOL(const std::string& name) +	{ +		return false; +	} +	virtual S32	getS32(const std::string& name) +	{ +		return 0; +	} +	virtual F32 getF32(const std::string& name) +	{ +		return 0; +	} +	virtual U32	getU32(const std::string& name) +	{ +		return test_preferred_maturity; +	} +	 +	//-------------------------------------- +	// Everything from here down is test code and not part of the interface +	void setPreferredMaturity(U32 m) +	{ +		test_preferred_maturity = m; +	} +private: +	U32 test_preferred_maturity; +	 +}; + +namespace tut +{ +    struct agentaccess +    { +    }; +     +	typedef test_group<agentaccess> agentaccess_t; +	typedef agentaccess_t::object agentaccess_object_t; +	tut::agentaccess_t tut_agentaccess("agentaccess"); + +	template<> template<> +	void agentaccess_object_t::test<1>() +	{ +		LLControlGroupReader_Test cgr; +		LLAgentAccess aa(cgr); +		 +		cgr.setPreferredMaturity(SIM_ACCESS_PG); +		ensure("1 prefersPG",     aa.prefersPG()); +		ensure("1 prefersMature", !aa.prefersMature()); +		ensure("1 prefersAdult",  !aa.prefersAdult()); +		 +		cgr.setPreferredMaturity(SIM_ACCESS_MATURE); +		ensure("2 prefersPG",     !aa.prefersPG()); +		ensure("2 prefersMature", aa.prefersMature()); +		ensure("2 prefersAdult",  !aa.prefersAdult()); +		 +		cgr.setPreferredMaturity(SIM_ACCESS_ADULT); +		ensure("3 prefersPG",     !aa.prefersPG()); +		ensure("3 prefersMature", aa.prefersMature()); +		ensure("3 prefersAdult",  aa.prefersAdult()); +    } +     +	template<> template<> +	void agentaccess_object_t::test<2>() +	{ +		LLControlGroupReader_Test cgr; +		LLAgentAccess aa(cgr); +		 +		// make sure default is PG +		ensure("1 isTeen",     aa.isTeen()); +		ensure("1 isMature",   !aa.isMature()); +		ensure("1 isAdult",    !aa.isAdult()); +		 +		// this is kinda bad -- setting this forces maturity to MATURE but !teen != Mature anymore +		aa.setTeen(false); +		ensure("2 isTeen",     !aa.isTeen()); +		ensure("2 isMature",   aa.isMature()); +		ensure("2 isAdult",    !aa.isAdult()); + +		// have to flip it back and make sure it still works +		aa.setTeen(true); +		ensure("3 isTeen",     aa.isTeen()); +		ensure("3 isMature",   !aa.isMature()); +		ensure("3 isAdult",    !aa.isAdult());		 + +		// check the conversion routine +		ensure_equals("1 conversion", SIM_ACCESS_PG, aa.convertTextToMaturity('P')); +		ensure_equals("2 conversion", SIM_ACCESS_MATURE, aa.convertTextToMaturity('M')); +		ensure_equals("3 conversion", SIM_ACCESS_ADULT, aa.convertTextToMaturity('A')); +		ensure_equals("4 conversion", SIM_ACCESS_MIN, aa.convertTextToMaturity('Q')); +		 +		// now try the other method of setting it - PG +		aa.setMaturity('P'); +		ensure("4 isTeen",     aa.isTeen()); +		ensure("4 isMature",   !aa.isMature()); +		ensure("4 isAdult",    !aa.isAdult()); +		 +		// Mature +		aa.setMaturity('M'); +		ensure("5 isTeen",     !aa.isTeen()); +		ensure("5 isMature",   aa.isMature()); +		ensure("5 isAdult",    !aa.isAdult()); +		 +		// Adult +		aa.setMaturity('A'); +		ensure("6 isTeen",     !aa.isTeen()); +		ensure("6 isMature",   aa.isMature()); +		ensure("6 isAdult",    aa.isAdult()); +		 +	} + +	template<> template<> +	void agentaccess_object_t::test<3>() +	{ +		LLControlGroupReader_Test cgr; +		LLAgentAccess aa(cgr); +		 +		ensure("starts normal", !aa.isGodlike()); +		aa.setGodLevel(GOD_NOT); +		ensure("stays normal", !aa.isGodlike()); +		aa.setGodLevel(GOD_FULL); +		ensure("sets full", aa.isGodlike()); +		aa.setGodLevel(GOD_NOT); +		ensure("resets normal", !aa.isGodlike()); +		aa.setAdminOverride(true); +		ensure("admin true", aa.getAdminOverride()); +		ensure("overrides 1", aa.isGodlike()); +		aa.setGodLevel(GOD_FULL); +		ensure("overrides 2", aa.isGodlike()); +		aa.setAdminOverride(false); +		ensure("admin false", !aa.getAdminOverride()); +		ensure("overrides 3", aa.isGodlike()); +    } +     +	template<> template<> +	void agentaccess_object_t::test<4>() +	{ +		LLControlGroupReader_Test cgr; +		LLAgentAccess aa(cgr); +		 +		ensure("1 pg to start", aa.wantsPGOnly()); +		ensure("2 pg to start", !aa.canAccessMature()); +		ensure("3 pg to start", !aa.canAccessAdult()); +		 +		aa.setGodLevel(GOD_FULL); +		ensure("1 full god", !aa.wantsPGOnly()); +		ensure("2 full god", aa.canAccessMature()); +		ensure("3 full god", aa.canAccessAdult()); +				 +		aa.setGodLevel(GOD_NOT); +		aa.setAdminOverride(true); +		ensure("1 admin mode", !aa.wantsPGOnly()); +		ensure("2 admin mode", aa.canAccessMature()); +		ensure("3 admin mode", aa.canAccessAdult()); + +		aa.setAdminOverride(false); +		aa.setMaturity('M'); +		// preferred is still pg by default +		ensure("1 mature pref pg", aa.wantsPGOnly()); +		ensure("2 mature pref pg", !aa.canAccessMature()); +		ensure("3 mature pref pg", !aa.canAccessAdult()); +		 +		cgr.setPreferredMaturity(SIM_ACCESS_MATURE); +		ensure("1 mature", !aa.wantsPGOnly()); +		ensure("2 mature", aa.canAccessMature()); +		ensure("3 mature", !aa.canAccessAdult()); +		 +		cgr.setPreferredMaturity(SIM_ACCESS_PG); +		ensure("1 mature pref pg", aa.wantsPGOnly()); +		ensure("2 mature pref pg", !aa.canAccessMature()); +		ensure("3 mature pref pg", !aa.canAccessAdult()); +		 +		aa.setMaturity('A'); +		ensure("1 adult pref pg", aa.wantsPGOnly()); +		ensure("2 adult pref pg", !aa.canAccessMature()); +		ensure("3 adult pref pg", !aa.canAccessAdult()); + +		cgr.setPreferredMaturity(SIM_ACCESS_ADULT); +		ensure("1 adult", !aa.wantsPGOnly()); +		ensure("2 adult", aa.canAccessMature()); +		ensure("3 adult", aa.canAccessAdult()); + +		// make sure that even if pref is high, if access is low we block access +		// this shouldn't occur in real life but we want to be safe +		cgr.setPreferredMaturity(SIM_ACCESS_ADULT); +		aa.setMaturity('P'); +		ensure("1 pref adult, actual pg", aa.wantsPGOnly()); +		ensure("2 pref adult, actual pg", !aa.canAccessMature()); +		ensure("3 pref adult, actual pg", !aa.canAccessAdult()); +		 +	} + +	template<> template<> +	void agentaccess_object_t::test<5>() +	{ +		LLControlGroupReader_Test cgr; +		LLAgentAccess aa(cgr); +		 +		ensure("1 transition starts false", !aa.isInTransition()); +		aa.setTransition(); +		ensure("2 transition now true", aa.isInTransition()); +	} + +} + +  | 
