diff options
Diffstat (limited to 'indra/newview')
25 files changed, 532 insertions, 120 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c5e1cde4e6..17e340d136 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -267,6 +267,7 @@ set(viewer_SOURCE_FILES      llfloaterregiondebugconsole.cpp      llfloaterregioninfo.cpp      llfloaterreporter.cpp +    llfloaterregionrestarting.cpp      llfloaterscriptdebug.cpp      llfloaterscriptlimits.cpp      llfloatersearch.cpp @@ -855,6 +856,7 @@ set(viewer_HEADER_FILES      llfloaterregiondebugconsole.h      llfloaterregioninfo.h      llfloaterreporter.h +    llfloaterregionrestarting.h      llfloaterscriptdebug.h      llfloaterscriptlimits.h      llfloatersearch.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index bf34fea635..db151817e0 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12632,6 +12632,17 @@        <key>Value</key>        <string>00000000-0000-0000-0000-000000000000</string>      </map> +    <key>UISndRestart</key> +    <map> +      <key>Comment</key> +      <string>Sound file for region restarting (uuid for sound asset)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string>b92a0f64-7709-8811-40c5-16afd624a45f</string> +    </map>      <key>UISndSnapshot</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 79da9e5873..f150ceda67 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -259,11 +259,9 @@ bool handleSlowMotionAnimation(const LLSD& newvalue)  	return true;  } -// static -void LLAgent::parcelChangedCallback() +void LLAgent::setCanEditParcel() // called via mParcelChangedSignal  {  	bool can_edit = LLToolMgr::getInstance()->canEdit(); -  	gAgent.mCanEditParcel = can_edit;  } @@ -425,6 +423,8 @@ LLAgent::LLAgent() :  	mListener.reset(new LLAgentListener(*this)); +	addParcelChangedCallback(&setCanEditParcel); +  	mMoveTimer.stop();  } @@ -451,8 +451,6 @@ void LLAgent::init()  	mLastKnownRequestMaturity = mLastKnownResponseMaturity;  	mIsDoSendMaturityPreferenceToServer = true; -	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback)); -  	if (!mTeleportFinishedSlot.connected())  	{  		mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this)); @@ -835,22 +833,33 @@ void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id)  	}  } +void LLAgent::changeParcels() +{ +	LL_DEBUGS("AgentLocation") << "Calling ParcelChanged callbacks" << LL_ENDL; +	// Notify anything that wants to know about parcel changes +	mParcelChangedSignal(); +} + +boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_callback_t cb) +{ +	return mParcelChangedSignal.connect(cb); +} +  //-----------------------------------------------------------------------------  // setRegion()  //-----------------------------------------------------------------------------  void LLAgent::setRegion(LLViewerRegion *regionp)  { -	bool teleport = true; - +	bool notifyRegionChange; +	  	llassert(regionp);  	if (mRegionp != regionp)  	{ -		// std::string host_name; -		// host_name = regionp->getHost().getHostName(); - +		notifyRegionChange = true; +		  		std::string ip = regionp->getHost().getString(); -		llinfos << "Moving agent into region: " << regionp->getName() -				<< " located at " << ip << llendl; +		LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName() +				<< " located at " << ip << LL_ENDL;  		if (mRegionp)  		{  			// We've changed regions, we're now going to change our agent coordinate frame. @@ -878,9 +887,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp)  			{  				gSky.mVOGroundp->setRegion(regionp);  			} - -			// Notify windlight managers -			teleport = (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE);  		}  		else  		{ @@ -902,8 +908,14 @@ void LLAgent::setRegion(LLViewerRegion *regionp)  		// Pass new region along to metrics components that care about this level of detail.  		LLAppViewer::metricsUpdateRegion(regionp->getHandle());  	} +	else +	{ +		notifyRegionChange = false; +	}  	mRegionp = regionp; +	// TODO - most of what follows probably should be moved into callbacks +  	// Pass the region host to LLUrlEntryParcel to resolve parcel name  	// with a server request.  	LLUrlEntryParcel::setRegionHost(getRegionHost()); @@ -922,15 +934,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp)  	LLFloaterMove::sUpdateFlyingStatus(); -	if (teleport) -	{ -		LLEnvManagerNew::instance().onTeleport(); -	} -	else -	{ -		LLEnvManagerNew::instance().onRegionCrossing(); -	} -  	// If the newly entered region is using server bakes, and our  	// current appearance is non-baked, request appearance update from  	// server. @@ -943,6 +946,12 @@ void LLAgent::setRegion(LLViewerRegion *regionp)  		// Need to handle via callback after caps arrive.  		mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::handleServerBakeRegionTransition,this,_1));  	} + +	if (notifyRegionChange) +	{ +		LL_DEBUGS("AgentLocation") << "Calling RegionChanged callbacks" << LL_ENDL; +		mRegionChangedSignal(); +	}  } @@ -967,6 +976,16 @@ LLHost LLAgent::getRegionHost() const  	}  } +boost::signals2::connection LLAgent::addRegionChangedCallback(const region_changed_signal_t::slot_type& cb) +{ +	return mRegionChangedSignal.connect(cb); +} + +void LLAgent::removeRegionChangedCallback(boost::signals2::connection callback) +{ +	mRegionChangedSignal.disconnect(callback); +} +  //-----------------------------------------------------------------------------  // inPrelude()  //----------------------------------------------------------------------------- diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 7fac17d098..0766407494 100755 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -231,15 +231,54 @@ private:  	LLVector3		mHomePosRegion;  	//-------------------------------------------------------------------- -	// Region +	// Parcel  	//--------------------------------------------------------------------  public: +	void changeParcels(); // called by LLViewerParcelMgr when we cross a parcel boundary +	 +	// Register a boost callback to be called when the agent changes parcels +	typedef boost::function<void()> parcel_changed_callback_t; +	boost::signals2::connection     addParcelChangedCallback(parcel_changed_callback_t); + +private: +	typedef boost::signals2::signal<void()> parcel_changed_signal_t; +	parcel_changed_signal_t		mParcelChangedSignal; + +	//-------------------------------------------------------------------- +	// Region +	//-------------------------------------------------------------------- +  public:  	void			setRegion(LLViewerRegion *regionp);  	LLViewerRegion	*getRegion() const;  	LLHost			getRegionHost() const;  	BOOL			inPrelude(); -private: + +	/** +	 * Register a boost callback to be called when the agent changes regions +	 * Note that if you need to access a capability for the region, you may need to wait +	 * for the capabilities to be received, since in some cases your region changed +	 * callback will be called before the capabilities have been received.  Your callback +	 * may need to look something like: +	 * +	 * 	 LLViewerRegion* region = gAgent.getRegion(); +	 * 	 if (region->capabilitiesReceived()) +	 * 	 { +	 *       useCapability(region); +	 * 	 } +	 * 	 else // Need to handle via callback after caps arrive. +	 * 	 { +	 *       region->setCapabilitiesReceivedCallback(boost::bind(&useCapability,region,_1)); +	 *       // you may or may not want to remove that callback +	 * 	 } +	 */ +	typedef boost::signals2::signal<void()> region_changed_signal_t; + +	boost::signals2::connection     addRegionChangedCallback(const region_changed_signal_t::slot_type& cb); +	void                            removeRegionChangedCallback(boost::signals2::connection callback); + +  private:  	LLViewerRegion	*mRegionp; +	region_changed_signal_t		            mRegionChangedSignal;  	//--------------------------------------------------------------------  	// History @@ -640,9 +679,10 @@ private:  public:  	bool			canEditParcel() const { return mCanEditParcel; }  private: +	static void     setCanEditParcel();  	bool			mCanEditParcel; -	static void parcelChangedCallback(); +  /********************************************************************************   **                                                                            ** diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp index 86fe6754dc..589cf28615 100755 --- a/indra/newview/llenvmanager.cpp +++ b/indra/newview/llenvmanager.cpp @@ -92,9 +92,11 @@ void LLEnvPrefs::setUseDayCycle(const std::string& name)  }  //============================================================================= -LLEnvManagerNew::LLEnvManagerNew() +LLEnvManagerNew::LLEnvManagerNew(): +	mInterpNextChangeMessage(true), +	mCurRegionUUID(LLUUID::null), +	mLastReceivedID(LLUUID::null)  { -	mInterpNextChangeMessage = true;  	// Set default environment settings.  	mUserPrefs.mUseRegionSettings = true; @@ -102,6 +104,9 @@ LLEnvManagerNew::LLEnvManagerNew()  	mUserPrefs.mWaterPresetName = "Default";  	mUserPrefs.mSkyPresetName = "Default";  	mUserPrefs.mDayCycleName = "Default"; + +	LL_DEBUGS("Windlight")<<LL_ENDL; +	gAgent.addRegionChangedCallback(boost::bind(&LLEnvManagerNew::onRegionChange, this));  }  bool LLEnvManagerNew::getUseRegionSettings() const @@ -300,6 +305,11 @@ void LLEnvManagerNew::loadUserPrefs()  	mUserPrefs.mUseRegionSettings	= gSavedSettings.getBOOL("UseEnvironmentFromRegion");  	mUserPrefs.mUseDayCycle			= gSavedSettings.getBOOL("UseDayCycle"); + +	if (mUserPrefs.mUseRegionSettings) +	{ +		requestRegionSettings(); +	}  }  void LLEnvManagerNew::saveUserPrefs() @@ -398,6 +408,7 @@ void LLEnvManagerNew::dumpPresets()  void LLEnvManagerNew::requestRegionSettings()  { +	LL_DEBUGS("Windlight") << LL_ENDL;  	LLEnvironmentRequest::initiate();  } @@ -422,11 +433,6 @@ boost::signals2::connection LLEnvManagerNew::setRegionSettingsChangeCallback(con  	return mRegionSettingsChangeSignal.connect(cb);  } -boost::signals2::connection LLEnvManagerNew::setRegionChangeCallback(const region_change_signal_t::slot_type& cb) -{ -	return mRegionChangeSignal.connect(cb); -} -  boost::signals2::connection LLEnvManagerNew::setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb)  {  	return mRegionSettingsAppliedSignal.connect(cb); @@ -457,25 +463,13 @@ const std::string LLEnvManagerNew::getScopeString(LLEnvKey::EScope scope)  	}  } -void LLEnvManagerNew::onRegionCrossing() -{ -	LL_DEBUGS("Windlight") << "Crossed region" << LL_ENDL; -	onRegionChange(true); -} - -void LLEnvManagerNew::onTeleport() -{ -	LL_DEBUGS("Windlight") << "Teleported" << LL_ENDL; -	onRegionChange(false); -} -  void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content)  {  	// If the message was valid, grab the UUID from it and save it for next outbound update message.  	mLastReceivedID = content[0]["messageID"].asUUID();  	// Refresh cached region settings. -	LL_DEBUGS("Windlight") << "Caching region environment settings: " << content << LL_ENDL; +	LL_DEBUGS("Windlight") << "Received region environment settings: " << content << LL_ENDL;  	F32 sun_hour = 0; // *TODO  	LLEnvironmentSettings new_settings(content[1], content[2], content[3], sun_hour);  	mCachedRegionPrefs = new_settings; @@ -594,6 +588,7 @@ void LLEnvManagerNew::updateWaterFromPrefs(bool interpolate)  void LLEnvManagerNew::updateManagersFromPrefs(bool interpolate)  { +	LL_DEBUGS("Windlight")<<LL_ENDL;  	// Apply water settings.  	updateWaterFromPrefs(interpolate); @@ -651,28 +646,35 @@ bool LLEnvManagerNew::useDefaultWater()  } -void LLEnvManagerNew::onRegionChange(bool interpolate) +void LLEnvManagerNew::onRegionChange()  {  	// Avoid duplicating region setting requests  	// by checking whether the region is actually changing.  	LLViewerRegion* regionp = gAgent.getRegion();  	LLUUID region_uuid = regionp ? regionp->getRegionID() : LLUUID::null; -	if (region_uuid == mCurRegionUUID) +	if (region_uuid != mCurRegionUUID)  	{ -		return; +		// Clear locally modified region settings. +		mNewRegionPrefs.clear(); + +		// *TODO: clear environment settings of the previous region? + +		// Request environment settings of the new region. +		mCurRegionUUID = region_uuid; +		// for region crossings, interpolate the change; for teleports, don't +		mInterpNextChangeMessage = (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE); +		LL_DEBUGS("Windlight") << (mInterpNextChangeMessage ? "Crossed" : "Teleported") +							   << " to new region: " << region_uuid +							   << LL_ENDL; +		requestRegionSettings(); +	} +	else +	{ +		LL_DEBUGS("Windlight") << "disregarding region change; interp: " +							   << (mInterpNextChangeMessage ? "true" : "false") +							   << " regionp: " << regionp +							   << " old: " << mCurRegionUUID +							   << " new: " << region_uuid +							   << LL_ENDL;  	} - -	// Clear locally modified region settings. -	mNewRegionPrefs.clear(); - -	// *TODO: clear environment settings of the previous region? - -	// Request environment settings of the new region. -	LL_DEBUGS("Windlight") << "New viewer region: " << region_uuid << LL_ENDL; -	mCurRegionUUID = region_uuid; -	mInterpNextChangeMessage = interpolate; -	requestRegionSettings(); - -	// Let interested parties know agent region has been changed. -	mRegionChangeSignal();  } diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h index ad56761bc7..c7877303fc 100755 --- a/indra/newview/llenvmanager.h +++ b/indra/newview/llenvmanager.h @@ -166,7 +166,6 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>  public:  	typedef boost::signals2::signal<void()> prefs_change_signal_t;  	typedef boost::signals2::signal<void()> region_settings_change_signal_t; -	typedef boost::signals2::signal<void()> region_change_signal_t;  	typedef boost::signals2::signal<void(bool)> region_settings_applied_signal_t;  	LLEnvManagerNew(); @@ -222,15 +221,12 @@ public:  	bool sendRegionSettings(const LLEnvironmentSettings& new_settings);  	boost::signals2::connection setPreferencesChangeCallback(const prefs_change_signal_t::slot_type& cb);  	boost::signals2::connection setRegionSettingsChangeCallback(const region_settings_change_signal_t::slot_type& cb); -	boost::signals2::connection setRegionChangeCallback(const region_change_signal_t::slot_type& cb);  	boost::signals2::connection setRegionSettingsAppliedCallback(const region_settings_applied_signal_t::slot_type& cb);  	static bool canEditRegionSettings(); /// @return true if we have access to editing region environment  	static const std::string getScopeString(LLEnvKey::EScope scope);  	// Public callbacks. -	void onRegionCrossing(); -	void onTeleport();  	void onRegionSettingsResponse(const LLSD& content);  	void onRegionSettingsApplyResponse(bool ok); @@ -251,7 +247,7 @@ private:  	bool useDefaultSky();  	bool useDefaultWater(); -	void onRegionChange(bool interpolate); +	void onRegionChange();  	/// Emitted when user environment preferences change.  	prefs_change_signal_t mUsePrefsChangeSignal; @@ -260,9 +256,6 @@ private:  	region_settings_change_signal_t	mRegionSettingsChangeSignal;  	/// Emitted when agent region changes. Move to LLAgent? -	region_change_signal_t	mRegionChangeSignal; - -	/// Emitted when agent region changes. Move to LLAgent?  	region_settings_applied_signal_t mRegionSettingsAppliedSignal;  	LLEnvPrefs				mUserPrefs;					/// User environment preferences. diff --git a/indra/newview/llfloatereditdaycycle.cpp b/indra/newview/llfloatereditdaycycle.cpp index b63677b258..78e20e3bf0 100755 --- a/indra/newview/llfloatereditdaycycle.cpp +++ b/indra/newview/llfloatereditdaycycle.cpp @@ -145,7 +145,7 @@ void LLFloaterEditDayCycle::initCallbacks(void)  	// Connect to env manager events.  	LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();  	env_mgr.setRegionSettingsChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsChange, this)); -	env_mgr.setRegionChangeCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this)); +	gAgent.addRegionChangedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionChange, this));  	env_mgr.setRegionSettingsAppliedCallback(boost::bind(&LLFloaterEditDayCycle::onRegionSettingsApplied, this, _1));  	// Connect to day cycle manager events. diff --git a/indra/newview/llfloaterpathfindingconsole.cpp b/indra/newview/llfloaterpathfindingconsole.cpp index 298454724b..161259d049 100755 --- a/indra/newview/llfloaterpathfindingconsole.cpp +++ b/indra/newview/llfloaterpathfindingconsole.cpp @@ -34,11 +34,11 @@  #include <boost/signals2.hpp> +#include "llagent.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llcombobox.h"  #include "llcontrol.h" -#include "llenvmanager.h"  #include "llfloaterpathfindingcharacters.h"  #include "llfloaterpathfindinglinksets.h"  #include "llfloaterreg.h" @@ -224,7 +224,7 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)  	if (!mRegionBoundarySlot.connected())  	{ -		mRegionBoundarySlot = LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this)); +		mRegionBoundarySlot = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterPathfindingConsole::onRegionBoundaryCross, this));  	}  	if (!mTeleportFailedSlot.connected()) diff --git a/indra/newview/llfloaterpathfindingobjects.cpp b/indra/newview/llfloaterpathfindingobjects.cpp index 20c1215bcb..d72ee073e1 100755 --- a/indra/newview/llfloaterpathfindingobjects.cpp +++ b/indra/newview/llfloaterpathfindingobjects.cpp @@ -41,7 +41,6 @@  #include "llavatarnamecache.h"  #include "llbutton.h"  #include "llcheckboxctrl.h" -#include "llenvmanager.h"  #include "llfloater.h"  #include "llfontgl.h"  #include "llnotifications.h" @@ -85,7 +84,7 @@ void LLFloaterPathfindingObjects::onOpen(const LLSD &pKey)  	if (!mRegionBoundaryCrossingSlot.connected())  	{ -		mRegionBoundaryCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this)); +		mRegionBoundaryCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this));  	}  	if (!mGodLevelChangeSlot.connected()) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 66bf49331b..73c0963a1d 100755 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -91,6 +91,7 @@  #include "lltrans.h"  #include "llagentui.h"  #include "llmeshrepository.h" +#include "llfloaterregionrestarting.h"  const S32 TERRAIN_TEXTURE_COUNT = 4;  const S32 CORNER_COUNT = 4; @@ -219,7 +220,7 @@ BOOL LLFloaterRegionInfo::postBuild()  		&processEstateOwnerRequest);  	// Request region info when agent region changes. -	LLEnvManagerNew::instance().setRegionChangeCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this)); +	gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionInfo::requestRegionInfo, this));  	return TRUE;  } diff --git a/indra/newview/llfloaterregionrestarting.cpp b/indra/newview/llfloaterregionrestarting.cpp new file mode 100644 index 0000000000..95d4265bb4 --- /dev/null +++ b/indra/newview/llfloaterregionrestarting.cpp @@ -0,0 +1,176 @@ +/**  + * @file llfloaterregionrestarting.cpp + * @brief Shows countdown timer during region restart + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterregionrestarting.h" + +#include "llfloaterreg.h" +#include "lluictrl.h" +#include "llagent.h" +#include "llagentcamera.h" +#include "llviewerwindow.h" + +static S32 sSeconds; +static U32 sShakeState; + +LLFloaterRegionRestarting::LLFloaterRegionRestarting(const LLSD& key) : +	LLFloater(key), +	LLEventTimer(1) +{ +	mName = (std::string)key["NAME"]; +	sSeconds = (LLSD::Integer)key["SECONDS"]; +} + +LLFloaterRegionRestarting::~LLFloaterRegionRestarting() +{ +	mRegionChangedConnection.disconnect(); +} + +BOOL LLFloaterRegionRestarting::postBuild() +{ +	mRegionChangedConnection = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterRegionRestarting::regionChange, this)); + +	LLStringUtil::format_map_t args; +	std::string text; + +	args["[NAME]"] = mName; +	text = getString("RegionName", args); +	LLTextBox* textbox = getChild<LLTextBox>("region_name"); +	textbox->setValue(text); + +	sShakeState = SHAKE_START; + +	refresh(); + +	return TRUE; +} + +void LLFloaterRegionRestarting::regionChange() +{ +	close(); +} + +BOOL LLFloaterRegionRestarting::tick() +{ +	refresh(); + +	return FALSE; +} + +void LLFloaterRegionRestarting::refresh() +{ +	LLStringUtil::format_map_t args; +	std::string text; + +	args["[SECONDS]"] = llformat("%d", sSeconds); +	getChild<LLTextBox>("restart_seconds")->setValue(getString("RestartSeconds", args)); + +	sSeconds = sSeconds - 1; +	if(sSeconds < 0.0) +	{ +		sSeconds = 0; +	} +} + +void LLFloaterRegionRestarting::draw() +{ +	LLFloater::draw(); + +	const F32 SHAKE_INTERVAL = 0.025; +	const F32 SHAKE_TOTAL_DURATION = 1.8; // the length of the default alert tone for this +	const F32 SHAKE_INITIAL_MAGNITUDE = 1.5; +	const F32 SHAKE_HORIZONTAL_BIAS = 0.25; +	F32 time_shaking; +	 +	if(SHAKE_START == sShakeState) +	{ +			mShakeTimer.setTimerExpirySec(SHAKE_INTERVAL); +			sShakeState = SHAKE_LEFT; +			mShakeIterations = 0; +			mShakeMagnitude = SHAKE_INITIAL_MAGNITUDE; +	} + +	if(SHAKE_DONE != sShakeState && mShakeTimer.hasExpired()) +	{ +		gAgentCamera.unlockView(); + +		switch(sShakeState) +		{ +			case SHAKE_LEFT: +				gAgentCamera.setPanLeftKey(mShakeMagnitude * SHAKE_HORIZONTAL_BIAS); +				sShakeState = SHAKE_UP; +				break; + +			case SHAKE_UP: +				gAgentCamera.setPanUpKey(mShakeMagnitude); +				sShakeState = SHAKE_RIGHT; +				break; + +			case SHAKE_RIGHT: +				gAgentCamera.setPanRightKey(mShakeMagnitude * SHAKE_HORIZONTAL_BIAS); +				sShakeState = SHAKE_DOWN; +				break; + +			case SHAKE_DOWN: +				gAgentCamera.setPanDownKey(mShakeMagnitude); +				mShakeIterations++; +				time_shaking = SHAKE_INTERVAL * (mShakeIterations * 4 /* left, up, right, down */); +				if(SHAKE_TOTAL_DURATION <= time_shaking) +				{ +					sShakeState = SHAKE_DONE; +					mShakeMagnitude = 0.0; +				} +				else +				{ +					sShakeState = SHAKE_LEFT; +					F32 percent_done_shaking = (SHAKE_TOTAL_DURATION - time_shaking) / SHAKE_TOTAL_DURATION; +					mShakeMagnitude = SHAKE_INITIAL_MAGNITUDE * (percent_done_shaking * percent_done_shaking); // exponential decay +				} +				break; + +			default: +				break; +		} +		mShakeTimer.setTimerExpirySec(SHAKE_INTERVAL); +	} +} + +void LLFloaterRegionRestarting::close() +{ +	LLFloaterRegionRestarting* floaterp = LLFloaterReg::findTypedInstance<LLFloaterRegionRestarting>("region_restarting"); + +	if (floaterp) +	{ +		floaterp->closeFloater(); +	} +} + +void LLFloaterRegionRestarting::updateTime(S32 time) +{ +	sSeconds = time; +	sShakeState = SHAKE_START; +} diff --git a/indra/newview/llfloaterregionrestarting.h b/indra/newview/llfloaterregionrestarting.h new file mode 100644 index 0000000000..46416db2c8 --- /dev/null +++ b/indra/newview/llfloaterregionrestarting.h @@ -0,0 +1,69 @@ +/**  + * @file llfloaterregionrestarting.h + * @brief Shows countdown timer during region restart + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERREGIONRESTARTING_H +#define LL_LLFLOATERREGIONRESTARTING_H + +#include "llfloater.h" +#include "lltextbox.h" +#include "lleventtimer.h" + +class LLFloaterRegionRestarting : public LLFloater,  public LLEventTimer +{ +	friend class LLFloaterReg; + +public: +	static void close(); +	static void updateTime(S32 time); + +private: +	LLFloaterRegionRestarting(const LLSD& key); +	virtual ~LLFloaterRegionRestarting(); +	virtual BOOL postBuild(); +	virtual BOOL tick(); +	virtual void refresh(); +	virtual void draw(); +	virtual void regionChange(); + +	std::string mName; +	U32 mShakeIterations; +	F32 mShakeMagnitude; +	LLTimer mShakeTimer; + +	boost::signals2::connection mRegionChangedConnection; + +	enum +	{ +		SHAKE_START, +		SHAKE_LEFT, +		SHAKE_UP, +		SHAKE_RIGHT, +		SHAKE_DOWN, +		SHAKE_DONE +	}; +}; + +#endif // LL_LLFLOATERREGIONRESTARTING_H diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 5022dba934..dbdff11f11 100755 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -407,14 +407,14 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)  	// - Make the "Add landmark" button updated when either current parcel gets changed  	//   or a landmark gets created or removed from the inventory.  	// - Update the location string on parcel change. -	mParcelMgrConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( +	mParcelMgrConnection = gAgent.addParcelChangedCallback(  		boost::bind(&LLLocationInputCtrl::onAgentParcelChange, this));  	// LLLocationHistory instance is being created before the location input control, so we have to update initial state of button manually.  	mButton->setEnabled(LLLocationHistory::instance().getItemCount() > 0);  	mLocationHistoryConnection = LLLocationHistory::getInstance()->setChangedCallback(  			boost::bind(&LLLocationInputCtrl::onLocationHistoryChanged, this,_1)); -	mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this)); +	mRegionCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLLocationInputCtrl::onRegionBoundaryCrossed, this));  	createNavMeshStatusListenerForCurrentRegion();  	mRemoveLandmarkObserver	= new LLRemoveLandmarkObserver(this); diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp index a567d1217a..8879cfd7fb 100755 --- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -79,7 +79,7 @@ void LLMenuOptionPathfindingRebakeNavmesh::initialize()  		if ( !mRegionCrossingSlot.connected() )  		{ -			mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); +			mRegionCrossingSlot = gAgent.addRegionChangedCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this));  		}  		if (!mAgentStateSlot.connected()) diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index eb6591eb39..32b168b8c5 100755 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -140,7 +140,7 @@ BOOL LLFloaterMove::postBuild()  	initMovementMode(); -	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(LLFloaterMove::sUpdateFlyingStatus); +	gAgent.addParcelChangedCallback(LLFloaterMove::sUpdateFlyingStatus);  	return TRUE;  } diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 6c2a01fc82..8bb3ace2d9 100755 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -251,7 +251,7 @@ LLPanelPlaces::LLPanelPlaces()  	gInventory.addObserver(mInventoryObserver); -	mAgentParcelChangedConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( +	mAgentParcelChangedConnection = gAgent.addParcelChangedCallback(  			boost::bind(&LLPanelPlaces::updateVerbs, this));  	//buildFromFile( "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder() diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 9dd665198f..0d09f0bbfc 100755 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -166,7 +166,7 @@ BOOL LLPanelTopInfoBar::postBuild()  		mShowCoordsCtrlConnection = ctrl->getSignal()->connect(boost::bind(&LLPanelTopInfoBar::onNavBarShowParcelPropertiesCtrlChanged, this));  	} -	mParcelMgrConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback( +	mParcelMgrConnection = gAgent.addParcelChangedCallback(  			boost::bind(&LLPanelTopInfoBar::onAgentParcelChange, this));  	setVisibleCallback(boost::bind(&LLPanelTopInfoBar::onVisibilityChange, this, _2)); diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 3da934b148..826d296117 100755 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -368,6 +368,7 @@ void init_audio()  		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTyping")));  		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose")));  		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndRestart")));  	}  	audio_update_volume(true); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 4ce049df03..a8eeddb798 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -95,6 +95,7 @@  #include "llfloaterproperties.h"  #include "llfloaterregiondebugconsole.h"  #include "llfloaterregioninfo.h" +#include "llfloaterregionrestarting.h"  #include "llfloaterreporter.h"  #include "llfloaterscriptdebug.h"  #include "llfloaterscriptlimits.h" @@ -296,6 +297,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("reset_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterResetQueue>);  	LLFloaterReg::add("region_debug_console", "floater_region_debug_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionDebugConsole>);  	LLFloaterReg::add("region_info", "floater_region_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionInfo>); +	LLFloaterReg::add("region_restarting", "floater_region_restarting.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionRestarting>);  	LLFloaterReg::add("script_debug", "floater_script_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebug>);  	LLFloaterReg::add("script_debug_output", "floater_script_debug_panel.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebugOutput>); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 3574d37adf..267aa9532c 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -111,6 +111,7 @@  #include "llpanelblockedlist.h"  #include "llpanelplaceprofile.h"  #include "llviewerregion.h" +#include "llfloaterregionrestarting.h"  #include <boost/algorithm/string/split.hpp> //  #include <boost/regex.hpp> @@ -5741,7 +5742,6 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)  	std::string regionMaturity = LLViewerRegion::accessToString(regionAccess);  	LLStringUtil::toLower(regionMaturity);  	llsdBlock["REGIONMATURITY"] = regionMaturity; -	  	bool returnValue = false;  	LLNotificationPtr maturityLevelNotification;  	std::string notifySuffix = "_Notify"; @@ -5911,6 +5911,7 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)  			(notificationID == "RegionEntryAccessBlocked") ||  			(notificationID == "LandClaimAccessBlocked") ||  			(notificationID == "LandBuyAccessBlocked") +  		   )  		{  			/*--------------------------------------------------------------------- @@ -5952,7 +5953,41 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)  			snap_filename += SCREEN_HOME_FILENAME;  			gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);  		} -		 + +		if (notificationID == "RegionRestartMinutes" || +			notificationID == "RegionRestartSeconds") +		{ +			S32 seconds; +			if (notificationID == "RegionRestartMinutes") +			{ +				seconds = 60 * static_cast<S32>(llsdBlock["MINUTES"].asInteger()); +			} +			else +			{ +				seconds = static_cast<S32>(llsdBlock["SECONDS"].asInteger()); +			} + +			LLFloaterRegionRestarting* floaterp = LLFloaterReg::findTypedInstance<LLFloaterRegionRestarting>("region_restarting"); + +			if (floaterp) +			{ +				LLFloaterRegionRestarting::updateTime(seconds); +			} +			else +			{ +				LLSD params; +				params["NAME"] = llsdBlock["NAME"]; +				params["SECONDS"] = (LLSD::Integer)seconds; +				LLFloaterRegionRestarting* restarting_floater = dynamic_cast<LLFloaterRegionRestarting*>(LLFloaterReg::showInstance("region_restarting", params)); +				if(restarting_floater) +				{ +					restarting_floater->center(); +				} +			} + +			send_sound_trigger(LLUUID(gSavedSettings.getString("UISndRestart")), 1.0f); +		} +  		LLNotificationsUtil::add(notificationID, llsdBlock);  		return true;  	}	 @@ -6012,7 +6047,6 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data)  	std::string message;  	msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, message); -  	process_special_alert_messages(message);  	if (!attempt_standard_notification(msgsystem)) @@ -6036,7 +6070,6 @@ bool handle_not_age_verified_alert(const std::string &pAlertName)  bool handle_special_alerts(const std::string &pAlertName)  {  	bool isHandled = false; -  	if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0)  	{ @@ -6072,26 +6105,17 @@ void process_alert_core(const std::string& message, BOOL modal)  		// System message is important, show in upper-right box not tip  		std::string text(message.substr(1));  		LLSD args; -		if (text.substr(0,17) == "RESTART_X_MINUTES") -		{ -			S32 mins = 0; -			LLStringUtil::convertToS32(text.substr(18), mins); -			args["MINUTES"] = llformat("%d",mins); -			LLNotificationsUtil::add("RegionRestartMinutes", args); -		} -		else if (text.substr(0,17) == "RESTART_X_SECONDS") -		{ -			S32 secs = 0; -			LLStringUtil::convertToS32(text.substr(18), secs); -			args["SECONDS"] = llformat("%d",secs); -			LLNotificationsUtil::add("RegionRestartSeconds", args); -		} -		else + +		// *NOTE: If the text from the server ever changes this line will need to be adjusted. +		std::string restart_cancelled = "Region restart cancelled."; +		if (text.substr(0, restart_cancelled.length()) == restart_cancelled)  		{ -			std::string new_msg =LLNotifications::instance().getGlobalString(text); -			args["MESSAGE"] = new_msg; -			LLNotificationsUtil::add("SystemMessage", args); +			LLFloaterRegionRestarting::close();  		} + +		std::string new_msg =LLNotifications::instance().getGlobalString(text); +		args["MESSAGE"] = new_msg; +		LLNotificationsUtil::add("SystemMessage", args);  	}  	else if (modal)  	{ diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 4cdb568d17..e361fad9de 100755 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1580,7 +1580,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use  			// Let interesting parties know about agent parcel change.  			LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance(); -			instance->mAgentParcelChangedSignal(); +			// Notify anything that wants to know when the agent changes parcels +			gAgent.changeParcels();  			if (instance->mTeleportInProgress)  			{ @@ -2458,10 +2459,6 @@ LLViewerTexture* LLViewerParcelMgr::getPassImage() const  	return sPassImage;  } -boost::signals2::connection LLViewerParcelMgr::addAgentParcelChangedCallback(parcel_changed_callback_t cb) -{ -	return mAgentParcelChangedSignal.connect(cb); -}  /*   * Set finish teleport callback. You can use it to observe all  teleport events.   * NOTE: @@ -2475,7 +2472,7 @@ boost::signals2::connection LLViewerParcelMgr::setTeleportFinishedCallback(telep  	return mTeleportFinishedSignal.connect(cb);  } -boost::signals2::connection LLViewerParcelMgr::setTeleportFailedCallback(parcel_changed_callback_t cb) +boost::signals2::connection LLViewerParcelMgr::setTeleportFailedCallback(teleport_failed_callback_t cb)  {  	return mTeleportFailedSignal.connect(cb);  } diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 6183b7e90e..9da49bb3f3 100755 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -80,8 +80,8 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>  public:  	typedef boost::function<void (const LLVector3d&, const bool& local)> teleport_finished_callback_t;  	typedef boost::signals2::signal<void (const LLVector3d&, const bool&)> teleport_finished_signal_t; -	typedef boost::function<void()> parcel_changed_callback_t; -	typedef boost::signals2::signal<void()> parcel_changed_signal_t; +	typedef boost::function<void()> teleport_failed_callback_t; +	typedef boost::signals2::signal<void()> teleport_failed_signal_t;  	LLViewerParcelMgr();  	~LLViewerParcelMgr(); @@ -283,9 +283,8 @@ public:  	// the agent is banned or not in the allowed group  	BOOL isCollisionBanned(); -	boost::signals2::connection addAgentParcelChangedCallback(parcel_changed_callback_t cb);  	boost::signals2::connection setTeleportFinishedCallback(teleport_finished_callback_t cb); -	boost::signals2::connection setTeleportFailedCallback(parcel_changed_callback_t cb); +	boost::signals2::connection setTeleportFailedCallback(teleport_failed_callback_t cb);  	void onTeleportFinished(bool local, const LLVector3d& new_pos);  	void onTeleportFailed(); @@ -338,8 +337,7 @@ private:  	BOOL						mTeleportInProgress;  	teleport_finished_signal_t	mTeleportFinishedSignal; -	parcel_changed_signal_t		mTeleportFailedSignal; -	parcel_changed_signal_t		mAgentParcelChangedSignal; +	teleport_failed_signal_t	mTeleportFailedSignal;  	// Array of pieces of parcel edges to potentially draw  	// Has (parcels_per_edge + 1) * (parcels_per_edge + 1) elements so diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 6f1a24d7f8..3ebb64e3fa 100755 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -122,6 +122,9 @@    <color        name="Blue_80"        value="0 0 1 0.8" /> +  <color +      name="Orange" +      value="1 .82 .46 1" />    <!-- This color name makes potentially unused colors show up bright purple.    Leave this here until all Unused? are removed below, otherwise diff --git a/indra/newview/skins/default/xui/en/floater_region_restarting.xml b/indra/newview/skins/default/xui/en/floater_region_restarting.xml new file mode 100644 index 0000000000..2fe4d0190a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_region_restarting.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + height="150" + width="290" + layout="topleft" + name="region_restarting" + help_topic="floater_region_restarting" + single_instance="true" + reuse_instance="false" + title="REGION RESTARTING"> +    <string name="RegionName"> +    The region you are in now ([NAME]) is about to restart. + +If you stay in this region you will be logged out. +    </string> +    <string name="RestartSeconds"> +     Seconds until restart +[SECONDS] +    </string> +    <panel +     name="layout_panel_1" +     height="150" +     width="290" +     follows="right|top" +     top="0" +     left="0" +     background_visible="true" +     bg_opaque_color="Orange" +     bg_alpha_color="Orange"> + +    <icon color="1.0 1.0 1.0 1.0" +     tab_stop="false" +     mouse_opaque="false" +     name="icon" +     width="32" +     height="32" +     image_name="notify_caution_icon.tga" +     follows="left|top"> +    </icon> + +    <text +     type="string" +     length="1" +     follows="top|left" +     layout="topleft" +     name="region_name" +     text_color="Black" +     font="SansSerifBold" +     word_wrap="true" +     height="100" +     top="5" +     left="40" +     width="230"> +    The region you are in now (-The longest region name-) is about to restart. + +If you stay in this region you will be logged out. +    </text> +    <text +     type="string" +     length="1" +     follows="top|left" +     layout="topleft" +     name="restart_seconds" +     text_color="Black" +     font="SansSerifLargeBold" +     height="40" +     top="110" +     left="0" +     halign="center" +     width="290"> +     Seconds until restart +     32767 +    </text> +  </panel> + </floater> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 35f2e7b31e..a93601f5fd 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6893,8 +6893,8 @@ This will add a bookmark in your inventory so you can quickly IM this Resident.    <notification     icon="notify.tga"     name="RegionRestartMinutes" +   show_toast="false"     priority="high" -   sound="UISndAlert"     type="notify">  The region "[NAME]" will restart in [MINUTES] minutes.  If you stay in this region you will be logged out. @@ -6903,8 +6903,8 @@ If you stay in this region you will be logged out.    <notification     icon="notify.tga"     name="RegionRestartSeconds" +   show_toast="false"     priority="high" -   sound="UISndAlert"     type="notify">  The region "[NAME]" will restart in [SECONDS] seconds.  If you stay in this region you will be logged out. | 
