diff options
45 files changed, 1097 insertions, 193 deletions
| diff --git a/indra/cmake/FMOD.cmake b/indra/cmake/FMOD.cmake index cb5124812d..cb5124812d 100755..100644 --- a/indra/cmake/FMOD.cmake +++ b/indra/cmake/FMOD.cmake diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index 320a9be8ab..320a9be8ab 100755..100644 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index 87c2d6775b..f5b242fdfc 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -49,7 +49,8 @@ typedef enum e_chat_type  	CHAT_TYPE_STOP = 5,  	CHAT_TYPE_DEBUG_MSG = 6,  	CHAT_TYPE_REGION = 7, -	CHAT_TYPE_OWNER = 8 +	CHAT_TYPE_OWNER = 8, +	CHAT_TYPE_DIRECT = 9		// From llRegionSayTo()  } EChatType;  typedef enum e_chat_audible_level diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp index 4dfaaed4e1..c87617c9ff 100644 --- a/indra/llwindow/llkeyboardheadless.cpp +++ b/indra/llwindow/llkeyboardheadless.cpp @@ -46,5 +46,28 @@ MASK LLKeyboardHeadless::currentMask(BOOL for_mouse_event)  { return MASK_NONE; }  void LLKeyboardHeadless::scanKeyboard() -{ }  +{ +	for (S32 key = 0; key < KEY_COUNT; key++) +	{ +		// Generate callback if any event has occurred on this key this frame. +		// Can't just test mKeyLevel, because this could be a slow frame and +		// key might have gone down then up. JC +		if (mKeyLevel[key] || mKeyDown[key] || mKeyUp[key]) +		{ +			mCurScanKey = key; +			mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); +		} +	} + +	// Reset edges for next frame +	for (S32 key = 0; key < KEY_COUNT; key++) +	{ +		mKeyUp[key] = FALSE; +		mKeyDown[key] = FALSE; +		if (mKeyLevel[key]) +		{ +			mKeyLevelFrameCount[key]++; +		} +	} +} diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp index 967c69fea9..7ffe53a307 100644 --- a/indra/lscript/lscript_library/lscript_library.cpp +++ b/indra/lscript/lscript_library/lscript_library.cpp @@ -461,6 +461,9 @@ void LLScriptLibrary::init()  	addFunction(10.f, 0.f, dummy_func, "llGetDisplayName", "s", "k");  	addFunction(10.f, 0.f, dummy_func, "llRequestDisplayName", "k", "k"); +	addFunction(10.f, 0.f, dummy_func, "llGetEnv", "s", "s"); +	addFunction(10.f, 0.f, dummy_func, "llRegionSayTo", NULL, "kis"); +  	// energy, sleep, dummy_func, name, return type, parameters, help text, gods-only  	// IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST. diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b1cb10665b..76a6c9f7b7 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -233,6 +233,7 @@ set(viewer_SOURCE_FILES      llfolderviewitem.cpp      llfollowcam.cpp      llfriendcard.cpp +    llgesturelistener.cpp      llgesturemgr.cpp      llgiveinventory.cpp      llglsandbox.cpp @@ -309,6 +310,7 @@ set(viewer_SOURCE_FILES      llnearbychat.cpp      llnearbychatbar.cpp      llnearbychathandler.cpp +    llnearbychatbarlistener.cpp      llnetmap.cpp      llnotificationalerthandler.cpp      llnotificationgrouphandler.cpp @@ -778,6 +780,7 @@ set(viewer_HEADER_FILES      llfolderviewitem.h      llfollowcam.h      llfriendcard.h +    llgesturelistener.h      llgesturemgr.h      llgiveinventory.h      llgroupactions.h @@ -853,6 +856,7 @@ set(viewer_HEADER_FILES      llnearbychat.h      llnearbychatbar.h      llnearbychathandler.h +    llnearbychatbarlistener.h      llnetmap.h      llnotificationhandler.h      llnotificationmanager.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d98f0da1c2..32b49ed760 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12261,6 +12261,17 @@  		<key>Value</key>  		<integer>1</integer>  	</map> +    <key>SLURLPassToOtherInstance</key> +    <map> +    <key>Comment</key> +    <string>Pass execution to prevoius viewer instances if there is a given slurl</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +    </map>      <key>soundsbeacon</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7d491a7774..fd5cee2772 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -198,6 +198,7 @@ LLAgent::LLAgent() :  	mAutoPilot(FALSE),  	mAutoPilotFlyOnStop(FALSE), +	mAutoPilotAllowFlying(TRUE),  	mAutoPilotTargetGlobal(),  	mAutoPilotStopDistance(1.f),  	mAutoPilotUseRotation(FALSE), @@ -1207,17 +1208,24 @@ BOOL LLAgent::getBusy() const  //-----------------------------------------------------------------------------  // startAutoPilotGlobal()  //----------------------------------------------------------------------------- -void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::string& behavior_name, const LLQuaternion *target_rotation, void (*finish_callback)(BOOL, void *),  void *callback_data, F32 stop_distance, F32 rot_threshold) +void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::string& behavior_name, const LLQuaternion *target_rotation, void (*finish_callback)(BOOL, void *),  void *callback_data, F32 stop_distance, F32 rot_threshold, BOOL allow_flying)  {  	if (!isAgentAvatarValid())  	{  		return;  	} +	// Are there any pending callbacks from previous auto pilot requests? +	if (mAutoPilotFinishedCallback) +	{ +		mAutoPilotFinishedCallback(dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData); +	} +  	mAutoPilotFinishedCallback = finish_callback;  	mAutoPilotCallbackData = callback_data;  	mAutoPilotRotationThreshold = rot_threshold;  	mAutoPilotBehaviorName = behavior_name; +	mAutoPilotAllowFlying = allow_flying;  	LLVector3d delta_pos( target_global );  	delta_pos -= getPositionGlobal(); @@ -1245,14 +1253,23 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s  		}  	} -	mAutoPilotFlyOnStop = getFlying(); +	if (mAutoPilotAllowFlying) +	{ +		mAutoPilotFlyOnStop = getFlying(); +	} +	else +	{ +		mAutoPilotFlyOnStop = FALSE; +	} -	if (distance > 30.0) +	if (distance > 30.0 && mAutoPilotAllowFlying)  	{  		setFlying(TRUE);  	} -	if ( distance > 1.f && heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f)) +	if ( distance > 1.f &&  +		mAutoPilotAllowFlying && +		heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f))  	{  		setFlying(TRUE);  		// Do not force flying for "Sit" behavior to prevent flying after pressing "Stand" @@ -1262,22 +1279,8 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s  	}  	mAutoPilot = TRUE; -	mAutoPilotTargetGlobal = target_global; - -	// trace ray down to find height of destination from ground -	LLVector3d traceEndPt = target_global; -	traceEndPt.mdV[VZ] -= 20.f; +	setAutoPilotTargetGlobal(target_global); -	LLVector3d targetOnGround; -	LLVector3 groundNorm; -	LLViewerObject *obj; - -	LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); -	F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); - -	// clamp z value of target to minimum height above ground -	mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height; -	mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal);  	if (target_rotation)  	{  		mAutoPilotUseRotation = TRUE; @@ -1295,12 +1298,36 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s  //----------------------------------------------------------------------------- -// startFollowPilot() +// setAutoPilotTargetGlobal  //----------------------------------------------------------------------------- -void LLAgent::startFollowPilot(const LLUUID &leader_id) +void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global)  { -	if (!mAutoPilot) return; +	if (mAutoPilot) +	{ +		mAutoPilotTargetGlobal = target_global; + +		// trace ray down to find height of destination from ground +		LLVector3d traceEndPt = target_global; +		traceEndPt.mdV[VZ] -= 20.f; + +		LLVector3d targetOnGround; +		LLVector3 groundNorm; +		LLViewerObject *obj; + +		LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); +		F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); + +		// clamp z value of target to minimum height above ground +		mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height; +		mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal); +	} +} +//----------------------------------------------------------------------------- +// startFollowPilot() +//----------------------------------------------------------------------------- +void LLAgent::startFollowPilot(const LLUUID &leader_id, BOOL allow_flying, F32 stop_distance) +{  	mLeaderID = leader_id;  	if ( mLeaderID.isNull() ) return; @@ -1311,7 +1338,14 @@ void LLAgent::startFollowPilot(const LLUUID &leader_id)  		return;  	} -	startAutoPilotGlobal(object->getPositionGlobal()); +	startAutoPilotGlobal(object->getPositionGlobal(),  +						 std::string(),	// behavior_name +						 NULL,			// target_rotation +						 NULL,			// finish_callback +						 NULL,			// callback_data +						 stop_distance, +						 0.03f,			// rotation_threshold +						 allow_flying);  } @@ -1338,6 +1372,7 @@ void LLAgent::stopAutoPilot(BOOL user_cancel)  		if (mAutoPilotFinishedCallback)  		{  			mAutoPilotFinishedCallback(!user_cancel && dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData); +			mAutoPilotFinishedCallback = NULL;  		}  		mLeaderID = LLUUID::null; @@ -1377,7 +1412,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)  		if (!isAgentAvatarValid()) return; -		if (gAgentAvatarp->mInAir) +		if (gAgentAvatarp->mInAir && mAutoPilotAllowFlying)  		{  			setFlying(TRUE);  		} diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 896408c0dd..33c05816e2 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -467,19 +467,29 @@ public:  public:  	BOOL			getAutoPilot() const				{ return mAutoPilot; }  	LLVector3d		getAutoPilotTargetGlobal() const 	{ return mAutoPilotTargetGlobal; } +	LLUUID			getAutoPilotLeaderID() const		{ return mLeaderID; } +	F32				getAutoPilotStopDistance() const	{ return mAutoPilotStopDistance; } +	F32				getAutoPilotTargetDist() const		{ return mAutoPilotTargetDist; } +	BOOL			getAutoPilotUseRotation() const		{ return mAutoPilotUseRotation; } +	LLVector3		getAutoPilotTargetFacing() const	{ return mAutoPilotTargetFacing; } +	F32				getAutoPilotRotationThreshold() const	{ return mAutoPilotRotationThreshold; } +	std::string		getAutoPilotBehaviorName() const	{ return mAutoPilotBehaviorName; } +  	void			startAutoPilotGlobal(const LLVector3d &pos_global,   										 const std::string& behavior_name = std::string(),   										 const LLQuaternion *target_rotation = NULL,   										 void (*finish_callback)(BOOL, void *) = NULL, void *callback_data = NULL,  -										 F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f); -	void 			startFollowPilot(const LLUUID &leader_id); +										 F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f, +										 BOOL allow_flying = TRUE); +	void 			startFollowPilot(const LLUUID &leader_id, BOOL allow_flying = TRUE, F32 stop_distance = 0.5f);  	void			stopAutoPilot(BOOL user_cancel = FALSE); -	void 			setAutoPilotGlobal(const LLVector3d &pos_global); +	void 			setAutoPilotTargetGlobal(const LLVector3d &target_global);  	void			autoPilot(F32 *delta_yaw); 			// Autopilot walking action, angles in radians  	void			renderAutoPilotTarget();  private:  	BOOL			mAutoPilot;  	BOOL			mAutoPilotFlyOnStop; +	BOOL			mAutoPilotAllowFlying;  	LLVector3d		mAutoPilotTargetGlobal;  	F32				mAutoPilotStopDistance;  	BOOL			mAutoPilotUseRotation; diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index ed24febf41..a328ae0ea1 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -31,6 +31,7 @@  #include "llagentlistener.h"  #include "llagent.h" +#include "llvoavatar.h"  #include "llcommandhandler.h"  #include "llslurl.h"  #include "llurldispatcher.h" @@ -39,82 +40,231 @@  #include "llviewerregion.h"  #include "llsdutil.h"  #include "llsdutil_math.h" +#include "lltoolgrab.h"  LLAgentListener::LLAgentListener(LLAgent &agent)    : LLEventAPI("LLAgent",                 "LLAgent listener to (e.g.) teleport, sit, stand, etc."),      mAgent(agent)  { -	add("requestTeleport", +    add("requestTeleport",          "Teleport: [\"regionname\"], [\"x\"], [\"y\"], [\"z\"]\n"          "If [\"skip_confirmation\"] is true, use LLURLDispatcher rather than LLCommandDispatcher.",          &LLAgentListener::requestTeleport); -	add("requestSit", -        "Ask to sit on the object specified in [\"obj_uuid\"]", +    add("requestSit", +		"[\"obj_uuid\"]: id of object to sit on, use this or [\"position\"] to indicate the sit target" +		"[\"position\"]: region position {x, y, z} where to find closest object to sit on",          &LLAgentListener::requestSit); -	add("requestStand", +    add("requestStand",          "Ask to stand up",          &LLAgentListener::requestStand); +    add("requestTouch", +		"[\"obj_uuid\"]: id of object to touch, use this or [\"position\"] to indicate the object to touch" +		"[\"position\"]: region position {x, y, z} where to find closest object to touch" +		"[\"face\"]: optional object face number to touch[Default: 0]", +        &LLAgentListener::requestTouch);      add("resetAxes",          "Set the agent to a fixed orientation (optionally specify [\"lookat\"] = array of [x, y, z])",          &LLAgentListener::resetAxes);      add("getAxes", +        "Obsolete - use getPosition instead\n"          "Send information about the agent's orientation on [\"reply\"]:\n"          "[\"euler\"]: map of {roll, pitch, yaw}\n"          "[\"quat\"]:  array of [x, y, z, w] quaternion values",          &LLAgentListener::getAxes,          LLSDMap("reply", LLSD())); +    add("getPosition", +        "Send information about the agent's position and orientation on [\"reply\"]:\n" +        "[\"region\"]: array of region {x, y, z} position\n" +        "[\"global\"]: array of global {x, y, z} position\n" +        "[\"euler\"]: map of {roll, pitch, yaw}\n" +        "[\"quat\"]:  array of [x, y, z, w] quaternion values", +        &LLAgentListener::getPosition, +        LLSDMap("reply", LLSD())); +    add("startAutoPilot", +        "Start the autopilot system using the following parameters:\n" +        "[\"target_global\"]: array of target global {x, y, z} position\n" +        "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]\n" +        "[\"target_rotation\"]: array of [x, y, z, w] quaternion values [default: no target]\n" +        "[\"rotation_threshold\"]: target maximum angle from target facing rotation [default: 0.03 radians]\n" +        "[\"behavior_name\"]: name of the autopilot behavior [default: \"\"]" +        "[\"allow_flying\"]: allow flying during autopilot [default: True]", +        //"[\"callback_pump\"]: pump to send success/failure and callback data to [default: none]\n" +        //"[\"callback_data\"]: data to send back during a callback [default: none]", +        &LLAgentListener::startAutoPilot); +    add("getAutoPilot", +        "Send information about current state of the autopilot system to [\"reply\"]:\n" +        "[\"enabled\"]: boolean indicating whether or not autopilot is enabled\n" +        "[\"target_global\"]: array of target global {x, y, z} position\n" +        "[\"leader_id\"]: uuid of target autopilot is following\n" +        "[\"stop_distance\"]: target maximum distance from target\n" +        "[\"target_distance\"]: last known distance from target\n" +        "[\"use_rotation\"]: boolean indicating if autopilot has a target facing rotation\n" +        "[\"target_facing\"]: array of {x, y} target direction to face\n" +        "[\"rotation_threshold\"]: target maximum angle from target facing rotation\n" +        "[\"behavior_name\"]: name of the autopilot behavior", +        &LLAgentListener::getAutoPilot, +        LLSDMap("reply", LLSD())); +    add("startFollowPilot", +		"[\"leader_id\"]: uuid of target to follow using the autopilot system (optional with avatar_name)\n" +		"[\"avatar_name\"]: avatar name to follow using the autopilot system (optional with leader_id)\n" +        "[\"allow_flying\"]: allow flying during autopilot [default: True]\n" +        "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]", +        &LLAgentListener::startFollowPilot); +    add("setAutoPilotTarget", +        "Update target for currently running autopilot:\n" +        "[\"target_global\"]: array of target global {x, y, z} position", +        &LLAgentListener::setAutoPilotTarget); +    add("stopAutoPilot", +        "Stop the autopilot system:\n" +        "[\"user_cancel\"] indicates whether or not to act as though user canceled autopilot [default: false]", +        &LLAgentListener::stopAutoPilot); +  }  void LLAgentListener::requestTeleport(LLSD const & event_data) const  { -	if(event_data["skip_confirmation"].asBoolean()) +    if(event_data["skip_confirmation"].asBoolean()) +    { +        LLSD params(LLSD::emptyArray()); +        params.append(event_data["regionname"]); +        params.append(event_data["x"]); +        params.append(event_data["y"]); +        params.append(event_data["z"]); +        LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, "clicked", true); +        // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat" +        // should we just compose LLCommandHandler and LLDispatchListener? +    } +    else +    { +        std::string url = LLSLURL(event_data["regionname"],  +                                  LLVector3(event_data["x"].asReal(),  +                                            event_data["y"].asReal(),  +                                            event_data["z"].asReal())).getSLURLString(); +        LLURLDispatcher::dispatch(url, "clicked", NULL, false); +    } +} + +void LLAgentListener::requestSit(LLSD const & event_data) const +{ +    //mAgent.getAvatarObject()->sitOnObject(); +    // shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand() +    // *TODO - find a permanent place to share this code properly. + +	LLViewerObject *object = NULL; +	if (event_data.has("obj_uuid")) +	{ +		object = gObjectList.findObject(event_data["obj_uuid"]); +	} +	else if (event_data.has("position"))  	{ -		LLSD params(LLSD::emptyArray()); -		params.append(event_data["regionname"]); -		params.append(event_data["x"]); -		params.append(event_data["y"]); -		params.append(event_data["z"]); -		LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, "clicked", true); -		// *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat" -		// should we just compose LLCommandHandler and LLDispatchListener? +		LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); +		object = findObjectClosestTo(target_position);  	} + +    if (object && object->getPCode() == LL_PCODE_VOLUME) +    { +        gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); +        gMessageSystem->nextBlockFast(_PREHASH_AgentData); +        gMessageSystem->addUUIDFast(_PREHASH_AgentID, mAgent.getID()); +        gMessageSystem->addUUIDFast(_PREHASH_SessionID, mAgent.getSessionID()); +        gMessageSystem->nextBlockFast(_PREHASH_TargetObject); +        gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); +        gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3(0,0,0)); + +        object->getRegion()->sendReliableMessage(); +    }  	else  	{ -		std::string url = LLSLURL(event_data["regionname"],  -								  LLVector3(event_data["x"].asReal(),  -											event_data["y"].asReal(),  -											event_data["z"].asReal())).getSLURLString(); -		LLURLDispatcher::dispatch(url, "clicked", NULL, false); +		llwarns << "LLAgent requestSit could not find the sit target: "  +			<< event_data << llendl;  	}  } -void LLAgentListener::requestSit(LLSD const & event_data) const +void LLAgentListener::requestStand(LLSD const & event_data) const  { -	//mAgent.getAvatarObject()->sitOnObject(); -	// shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand() -	// *TODO - find a permanent place to share this code properly. -	LLViewerObject *object = gObjectList.findObject(event_data["obj_uuid"]); +    mAgent.setControlFlags(AGENT_CONTROL_STAND_UP); +} -	if (object && object->getPCode() == LL_PCODE_VOLUME) -	{ -		gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); -		gMessageSystem->nextBlockFast(_PREHASH_AgentData); -		gMessageSystem->addUUIDFast(_PREHASH_AgentID, mAgent.getID()); -		gMessageSystem->addUUIDFast(_PREHASH_SessionID, mAgent.getSessionID()); -		gMessageSystem->nextBlockFast(_PREHASH_TargetObject); -		gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); -		gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3(0,0,0)); -		object->getRegion()->sendReliableMessage(); +LLViewerObject * LLAgentListener::findObjectClosestTo( const LLVector3 & position ) const +{ +	LLViewerObject *object = NULL; + +	// Find the object closest to that position +	F32 min_distance = 10000.0f;		// Start big +	S32 num_objects = gObjectList.getNumObjects(); +	S32 cur_index = 0; +	while (cur_index < num_objects) +	{ +		LLViewerObject * cur_object = gObjectList.getObject(cur_index++); +		if (cur_object) +		{	// Calculate distance from the target position +			LLVector3 target_diff = cur_object->getPositionRegion() - position; +			F32 distance_to_target = target_diff.length(); +			if (distance_to_target < min_distance) +			{	// Found an object closer +				min_distance = distance_to_target; +				object = cur_object; +			} +		}  	} + +	return object;  } -void LLAgentListener::requestStand(LLSD const & event_data) const + +void LLAgentListener::requestTouch(LLSD const & event_data) const  { -	mAgent.setControlFlags(AGENT_CONTROL_STAND_UP); +	LLViewerObject *object = NULL; +	 +	if (event_data.has("obj_uuid")) +	{ +		object = gObjectList.findObject(event_data["obj_uuid"]); +	} +	else if (event_data.has("position")) +	{ +		LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); +		object = findObjectClosestTo(target_position); +	} + +	S32 face = 0; +	if (event_data.has("face")) +	{ +		face = event_data["face"].asInteger(); +	} + +    if (object && object->getPCode() == LL_PCODE_VOLUME) +    { +		// Fake enough pick info to get it to (hopefully) work +		LLPickInfo pick; +		pick.mObjectFace = face; + +		/* +		These values are sent to the simulator, but face seems to be easiest to use + +		pick.mUVCoords	 "UVCoord" +		pick.mSTCoords	"STCoord"	 +		pick.mObjectFace	"FaceIndex" +		pick.mIntersection	"Position" +		pick.mNormal	"Normal" +		pick.mBinormal	"Binormal" +		*/ + +		// A touch is a sketchy message sequence ... send a grab, immediately +		// followed by un-grabbing, crossing fingers and hoping packets arrive in +		// the correct order +		send_ObjectGrab_message(object, pick, LLVector3::zero); +		send_ObjectDeGrab_message(object, pick); +    } +	else +	{ +		llwarns << "LLAgent requestTouch could not find the touch target "  +			<< event_data["obj_uuid"].asUUID() << llendl; +	}  } +  void LLAgentListener::resetAxes(const LLSD& event) const  {      if (event.has("lookat")) @@ -135,8 +285,183 @@ void LLAgentListener::getAxes(const LLSD& event) const      quat.getEulerAngles(&roll, &pitch, &yaw);      // The official query API for LLQuaternion's [x, y, z, w] values is its      // public member mQ... -    sendReply(LLSDMap -              ("quat", llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ))) -              ("euler", LLSDMap("roll", roll)("pitch", pitch)("yaw", yaw)), -              event); +	LLSD reply = LLSD::emptyMap(); +	reply["quat"] = llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ)); +	reply["euler"] = LLSD::emptyMap(); +	reply["euler"]["roll"] = roll; +	reply["euler"]["pitch"] = pitch; +	reply["euler"]["yaw"] = yaw; +    sendReply(reply, event);  } + +void LLAgentListener::getPosition(const LLSD& event) const +{ +    F32 roll, pitch, yaw; +    LLQuaternion quat(mAgent.getQuat()); +    quat.getEulerAngles(&roll, &pitch, &yaw); + +	LLSD reply = LLSD::emptyMap(); +	reply["quat"] = llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ)); +	reply["euler"] = LLSD::emptyMap(); +	reply["euler"]["roll"] = roll; +	reply["euler"]["pitch"] = pitch; +	reply["euler"]["yaw"] = yaw; +    reply["region"] = ll_sd_from_vector3(mAgent.getPositionAgent()); +    reply["global"] = ll_sd_from_vector3d(mAgent.getPositionGlobal()); + +	sendReply(reply, event); +} + + +void LLAgentListener::startAutoPilot(LLSD const & event) +{ +    LLQuaternion target_rotation_value; +    LLQuaternion* target_rotation = NULL; +    if (event.has("target_rotation")) +    { +        target_rotation_value = ll_quaternion_from_sd(event["target_rotation"]); +        target_rotation = &target_rotation_value; +    } +    // *TODO: Use callback_pump and callback_data +    F32 rotation_threshold = 0.03f; +    if (event.has("rotation_threshold")) +    { +        rotation_threshold = event["rotation_threshold"].asReal(); +    } +	 +	BOOL allow_flying = TRUE; +	if (event.has("allow_flying")) +	{ +		allow_flying = (BOOL) event["allow_flying"].asBoolean(); +		if (!allow_flying) +		{ +			mAgent.setFlying(FALSE); +		} +	} + +	F32 stop_distance = 0.f; +	if (event.has("stop_distance")) +	{ +		stop_distance = event["stop_distance"].asReal(); +	} + +	// Clear follow target, this is doing a path +	mFollowTarget.setNull(); + +    mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event["target_global"]), +                                event["behavior_name"], +                                target_rotation, +                                NULL, NULL, +                                stop_distance, +                                rotation_threshold, +								allow_flying); +} + +void LLAgentListener::getAutoPilot(const LLSD& event) const +{ +	LLSD reply = LLSD::emptyMap(); +	 +	LLSD::Boolean enabled = mAgent.getAutoPilot(); +	reply["enabled"] = enabled; +	 +	reply["target_global"] = ll_sd_from_vector3d(mAgent.getAutoPilotTargetGlobal()); +	 +	reply["leader_id"] = mAgent.getAutoPilotLeaderID(); +	 +	reply["stop_distance"] = mAgent.getAutoPilotStopDistance(); + +	reply["target_distance"] = mAgent.getAutoPilotTargetDist(); +	if (!enabled && +		mFollowTarget.notNull()) +	{	// Get an actual distance from the target object we were following +		LLViewerObject * target = gObjectList.findObject(mFollowTarget); +		if (target) +		{	// Found the target AV, return the actual distance to them as well as their ID +			LLVector3 difference = target->getPositionRegion() - mAgent.getPositionAgent(); +			reply["target_distance"] = difference.length(); +			reply["leader_id"] = mFollowTarget; +		} +	} + +	reply["use_rotation"] = (LLSD::Boolean) mAgent.getAutoPilotUseRotation(); +	reply["target_facing"] = ll_sd_from_vector3(mAgent.getAutoPilotTargetFacing()); +	reply["rotation_threshold"] = mAgent.getAutoPilotRotationThreshold(); +	reply["behavior_name"] = mAgent.getAutoPilotBehaviorName(); +	reply["fly"] = (LLSD::Boolean) mAgent.getFlying(); + +	sendReply(reply, event); +} + +void LLAgentListener::startFollowPilot(LLSD const & event) +{ +	LLUUID target_id; + +	BOOL allow_flying = TRUE; +	if (event.has("allow_flying")) +	{ +		allow_flying = (BOOL) event["allow_flying"].asBoolean(); +	} + +	if (event.has("leader_id")) +	{ +		target_id = event["leader_id"]; +	} +	else if (event.has("avatar_name")) +	{	// Find the avatar with matching name +		std::string target_name = event["avatar_name"].asString(); + +		if (target_name.length() > 0) +		{ +			S32 num_objects = gObjectList.getNumObjects(); +			S32 cur_index = 0; +			while (cur_index < num_objects) +			{ +				LLViewerObject * cur_object = gObjectList.getObject(cur_index++); +				if (cur_object && +					cur_object->asAvatar() && +					cur_object->asAvatar()->getFullname() == target_name) +				{	// Found avatar with matching name, extract id and break out of loop +					target_id = cur_object->getID(); +					break; +				} +			} +		} +	} + +	F32 stop_distance = 0.f; +	if (event.has("stop_distance")) +	{ +		stop_distance = event["stop_distance"].asReal(); +	} + +	if (target_id.notNull()) +	{ +		if (!allow_flying) +		{ +			mAgent.setFlying(FALSE); +		} +		mFollowTarget = target_id;	// Save follow target so we can report distance later + +	    mAgent.startFollowPilot(target_id, allow_flying, stop_distance); +	} +} + +void LLAgentListener::setAutoPilotTarget(LLSD const & event) const +{ +	if (event.has("target_global")) +	{ +		LLVector3d target_global(ll_vector3d_from_sd(event["target_global"])); +		mAgent.setAutoPilotTargetGlobal(target_global); +	} +} + +void LLAgentListener::stopAutoPilot(LLSD const & event) const +{ +	BOOL user_cancel = FALSE; +	if (event.has("user_cancel")) +	{ +		user_cancel = event["user_cancel"].asBoolean(); +	} +    mAgent.stopAutoPilot(user_cancel); +} + diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index 0aa58d0b16..c917151b71 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -34,21 +34,33 @@  class LLAgent;  class LLSD; +class LLViewerObject;  +class LLVector3d;  class LLAgentListener : public LLEventAPI  {  public: -	LLAgentListener(LLAgent &agent); +    LLAgentListener(LLAgent &agent);  private: -	void requestTeleport(LLSD const & event_data) const; -	void requestSit(LLSD const & event_data) const; -	void requestStand(LLSD const & event_data) const; -	void resetAxes(const LLSD& event) const; -	void getAxes(const LLSD& event) const; +    void requestTeleport(LLSD const & event_data) const; +    void requestSit(LLSD const & event_data) const; +    void requestStand(LLSD const & event_data) const; +    void requestTouch(LLSD const & event_data) const; +    void resetAxes(const LLSD& event) const; +    void getAxes(const LLSD& event) const; +    void getPosition(const LLSD& event) const; +    void startAutoPilot(const LLSD& event); +    void getAutoPilot(const LLSD& event) const; +    void startFollowPilot(const LLSD& event); +    void setAutoPilotTarget(const LLSD& event) const; +    void stopAutoPilot(const LLSD& event) const; + +	LLViewerObject * findObjectClosestTo( const LLVector3 & position ) const;  private: -	LLAgent & mAgent; +    LLAgent &	mAgent; +	LLUUID		mFollowTarget;  };  #endif // LL_LLAGENTLISTENER_H diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index cbd996f909..90c9912d1d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1162,11 +1162,11 @@ bool LLAppViewer::mainLoop()  				// Scan keyboard for movement keys.  Command keys and typing  				// are handled by windows callbacks.  Don't do this until we're  				// done initializing.  JC -				if (gViewerWindow->mWindow->getVisible()  +				if ((gHeadlessClient || gViewerWindow->mWindow->getVisible())  					&& gViewerWindow->getActive()  					&& !gViewerWindow->mWindow->getMinimized()  					&& LLStartUp::getStartupState() == STATE_STARTED -					&& !gViewerWindow->getShowProgress() +					&& (gHeadlessClient || !gViewerWindow->getShowProgress())  					&& !gFocusMgr.focusLocked())  				{  					LLMemType mjk(LLMemType::MTYPE_JOY_KEY); @@ -2458,7 +2458,8 @@ bool LLAppViewer::initConfiguration()  	// it relies on checking a marker file which will not work when running  	// out of different directories -	if (LLStartUp::getStartSLURL().isValid()) +	if (LLStartUp::getStartSLURL().isValid() && +		(gSavedSettings.getBOOL("SLURLPassToOtherInstance")))  	{  		if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString()))  		{ diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index d328567a0e..b9d546de59 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -301,23 +301,44 @@ void create_console()  	// redirect unbuffered STDOUT to the console  	l_std_handle = (long)GetStdHandle(STD_OUTPUT_HANDLE);  	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); -	fp = _fdopen( h_con_handle, "w" ); -	*stdout = *fp; -	setvbuf( stdout, NULL, _IONBF, 0 ); +	if (h_con_handle == -1) +	{ +		llwarns << "create_console() failed to open stdout handle" << llendl; +	} +	else +	{ +		fp = _fdopen( h_con_handle, "w" ); +		*stdout = *fp; +		setvbuf( stdout, NULL, _IONBF, 0 ); +	}  	// redirect unbuffered STDIN to the console  	l_std_handle = (long)GetStdHandle(STD_INPUT_HANDLE);  	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); -	fp = _fdopen( h_con_handle, "r" ); -	*stdin = *fp; -	setvbuf( stdin, NULL, _IONBF, 0 ); +	if (h_con_handle == -1) +	{ +		llwarns << "create_console() failed to open stdin handle" << llendl; +	} +	else +	{ +		fp = _fdopen( h_con_handle, "r" ); +		*stdin = *fp; +		setvbuf( stdin, NULL, _IONBF, 0 ); +	}  	// redirect unbuffered STDERR to the console  	l_std_handle = (long)GetStdHandle(STD_ERROR_HANDLE);  	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); -	fp = _fdopen( h_con_handle, "w" ); -	*stderr = *fp; -	setvbuf( stderr, NULL, _IONBF, 0 ); +	if (h_con_handle == -1) +	{ +		llwarns << "create_console() failed to open stderr handle" << llendl; +	} +	else +	{ +		fp = _fdopen( h_con_handle, "w" ); +		*stderr = *fp; +		setvbuf( stderr, NULL, _IONBF, 0 ); +	}  }  LLAppViewerWin32::LLAppViewerWin32(const char* cmd_line) : diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index ca7ec7cc30..ca7ec7cc30 100644..100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 0371b7be71..919f8ef666 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -46,6 +46,7 @@  #include "llhints.h"  #include "llimfloater.h" // for LLIMFloater  #include "llnearbychatbar.h" +#include "llnearbychatbarlistener.h"  #include "llsidetray.h"  #include "llspeakbutton.h"  #include "llsplitbutton.h" @@ -556,6 +557,8 @@ BOOL LLBottomTray::postBuild()  	mNearbyChatBar = findChild<LLNearbyChatBar>("chat_bar");  	LLHints::registerHintTarget("chat_bar", mNearbyChatBar->LLView::getHandle()); +	mListener.reset(new LLNearbyChatBarListener(*mNearbyChatBar)); +  	mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel");  	mNearbyCharResizeHandlePanel = getChild<LLPanel>("chat_bar_resize_handle_panel"); diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 04e5f5e9e0..83a33845bf 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -39,6 +39,7 @@ class LLIMChiclet;  class LLBottomTrayLite;  class LLLayoutPanel;  class LLMenuGL; +class LLNearbyChatBarListener;  // Build time optimization, generate once in .cpp file  #ifndef LLBOTTOMTRAY_CPP @@ -508,6 +509,9 @@ protected:  	 * Image used to show position where dragged button will be dropped.  	 */  	LLUIImage* mImageDragIndication; + +	// We want only one LLNearbyChatBarListener object, so it's tied to this singleton +	boost::shared_ptr<LLNearbyChatBarListener> mListener;  };  #endif // LL_LLBOTTOMPANEL_H diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 6e58be8174..cf0374075a 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -671,6 +671,9 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl)  	}  } + +/* Cruft - global gChatHandler declared below has been commented out, +   so this class is never used.  See similar code in llnearbychatbar.cpp  class LLChatHandler : public LLCommandHandler  {  public: @@ -691,7 +694,7 @@ public:  		{  		S32 channel = tokens[0].asInteger();  			// VWR-19499 Restrict function to chat channels greater than 0. -			if ((channel > 0) && (channel < 2147483647)) +			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))  			{  				retval = true;  				// Say mesg on channel @@ -710,3 +713,4 @@ public:  // Creating the object registers with the dispatcher.  //LLChatHandler gChatHandler; +cruft */ diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index 19dba3f917..19dba3f917 100644..100755 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 1a9d0af9af..1a9d0af9af 100644..100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 03cf0332a9..03cf0332a9 100644..100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp diff --git a/indra/newview/llgesturelistener.cpp b/indra/newview/llgesturelistener.cpp new file mode 100644 index 0000000000..22b7d233c5 --- /dev/null +++ b/indra/newview/llgesturelistener.cpp @@ -0,0 +1,159 @@ +/**
 + * @file   llgesturelistener.cpp
 + * @author Dave Simmons
 + * @date   2011-03-28
 + * @brief  Implementation for LLGestureListener.
 + *
 + * $LicenseInfo:firstyear=2011&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2011, 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 "llgesturelistener.h"
 +#include "llgesturemgr.h"
 +#include "llmultigesture.h"
 +
 +
 +LLGestureListener::LLGestureListener()
 +  : LLEventAPI("LLGesture",
 +               "LLGesture listener interface to control gestures")
 +{
 +    add("getActiveGestures",
 +        "Return information about the agent's available gestures [\"reply\"]:\n"
 +        "[\"gestures\"]: a dictionary with UUID strings as keys\n"
 +		"  and the following dict values for each entry:\n"
 +		"     [\"name\"]: name of the gesture, may be empty\n"
 +		"     [\"trigger\"]: trigger string used to invoke via user chat, may be empty\n"
 +		"     [\"playing\"]: true or false indicating the playing state",
 +        &LLGestureListener::getActiveGestures,
 +        LLSDMap("reply", LLSD()));
 +	add("isGesturePlaying",
 +		"[\"id\"]: UUID of the gesture to query.  Returns True or False in [\"playing\"] value of the result",
 +        &LLGestureListener::isGesturePlaying);
 +	add("startGesture",
 +		"[\"id\"]: UUID of the gesture to start playing",
 +        &LLGestureListener::startGesture);
 +	add("stopGesture",
 +		"[\"id\"]: UUID of the gesture to stop",
 +        &LLGestureListener::stopGesture);
 +}
 +
 +
 +// "getActiveGestures" command
 +void LLGestureListener::getActiveGestures(const LLSD& event_data) const
 +{
 +	LLSD reply = LLSD::emptyMap();
 +	LLSD gesture_map = LLSD::emptyMap();
 +
 +	const LLGestureMgr::item_map_t& active_gestures = LLGestureMgr::instance().getActiveGestures();
 +
 +	// Scan active gesture map and get all the names
 +	LLGestureMgr::item_map_t::const_iterator it;
 +	for (it = active_gestures.begin(); it != active_gestures.end(); ++it)
 +	{
 +		LLMultiGesture* gesture = (*it).second;
 +		if (gesture)
 +		{	// Add an entry to the result map with the LLUUID as key with a map containing data
 +			LLSD info = LLSD::emptyMap();
 +			info["name"] = (LLSD::String) gesture->mName;
 +			info["trigger"] = (LLSD::String) gesture->mTrigger;
 +			info["playing"] = (LLSD::Boolean) gesture->mPlaying;
 +
 +			gesture_map[(*it).first.asString()] = info;
 +		}
 +	}
 +
 +	reply["gestures"] = gesture_map;
 +	sendReply(reply, event_data);
 +}
 +
 +
 +
 +// "isGesturePlaying" command
 +void LLGestureListener::isGesturePlaying(const LLSD& event_data) const
 +{
 +	bool is_playing = false;
 +	if (event_data.has("id"))
 +	{
 +		LLUUID gesture_id = event_data["id"].asUUID();
 +		if (gesture_id.notNull())
 +		{
 +			is_playing = LLGestureMgr::instance().isGesturePlaying(gesture_id);
 +		}
 +		else
 +		{
 +			llwarns << "isGesturePlaying did not find a gesture object for " << gesture_id << llendl;
 +		}
 +	}
 +	else
 +	{
 +		llwarns << "isGesturePlaying didn't have 'id' value passed in" << llendl;
 +	}
 +
 +	LLSD reply = LLSD::emptyMap();
 +	reply["playing"] = (LLSD::Boolean) is_playing;
 +	sendReply(reply, event_data);
 +}
 +
 +
 +// "startGesture" command
 +void LLGestureListener::startGesture(LLSD const & event_data) const
 +{
 +	startOrStopGesture(event_data, true);
 +}
 +
 +
 +// "stopGesture" command
 +void LLGestureListener::stopGesture(LLSD const & event_data) const
 +{
 +	startOrStopGesture(event_data, false);
 +}
 +
 +
 +// Real code for "startGesture" or "stopGesture"
 +void LLGestureListener::startOrStopGesture(LLSD const & event_data, bool start) const
 +{
 +	if (event_data.has("id"))
 +	{
 +		LLUUID gesture_id = event_data["id"].asUUID();
 +		if (gesture_id.notNull())
 +		{
 +			if (start)
 +			{
 +				LLGestureMgr::instance().playGesture(gesture_id);
 +			}
 +			else
 +			{
 +				LLGestureMgr::instance().stopGesture(gesture_id);
 +			}
 +		}
 +		else
 +		{
 +			llwarns << "startOrStopGesture did not find a gesture object for " << gesture_id << llendl;
 +		}
 +	}
 +	else
 +	{
 +		llwarns << "startOrStopGesture didn't have 'id' value passed in" << llendl;
 +	}
 +}
 +
 diff --git a/indra/newview/llgesturelistener.h b/indra/newview/llgesturelistener.h new file mode 100644 index 0000000000..326881ac2b --- /dev/null +++ b/indra/newview/llgesturelistener.h @@ -0,0 +1,52 @@ +/**
 + * @file   llgesturelistener.h
 + * @author Dave Simmons
 + * @date   2011-03-15
 + * @brief  Class definition for LLGestureListener.
 + *
 + * $LicenseInfo:firstyear=2011&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2011, 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_LLGESTURELISTENER_H
 +#define LL_LLGESTURELISTENER_H
 +
 +#include "lleventapi.h"
 +
 +class LLSD;
 +
 +class LLGestureListener : public LLEventAPI
 +{
 +public:
 +	LLGestureListener();
 +
 +private:
 +    void getActiveGestures(LLSD const & gesture_data) const;
 +	void isGesturePlaying(LLSD const & gesture_data) const;
 +    void startGesture(LLSD const & gesture_data) const;
 +    void stopGesture(LLSD const & gesture_data) const;
 +
 +	void startOrStopGesture(LLSD const & event_data, bool start) const;
 +};
 +
 +#endif // LL_LLGESTURELISTENER_H
 +
 diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index f658287fb1..c5b821c360 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -51,6 +51,7 @@  #include "llviewerstats.h"  #include "llnearbychatbar.h"  #include "llappearancemgr.h" +#include "llgesturelistener.h"  // Longest time, in seconds, to wait for all animations to stop playing  const F32 MAX_WAIT_ANIM_SECS = 30.f; @@ -68,6 +69,7 @@ LLGestureMgr::LLGestureMgr()  	mLoadingCount(0)  {  	gInventory.addObserver(this); +	mListener.reset(new LLGestureListener());  } diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index b9935efeb3..e305895797 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -37,6 +37,7 @@  #include "llviewerinventory.h"  class LLMultiGesture; +class LLGestureListener;  class LLGestureStep;  class LLUUID;  class LLVFS; @@ -172,6 +173,9 @@ private:  	callback_map_t mCallbackMap;  	std::vector<LLMultiGesture*> mPlaying;	  	BOOL mValid; + +	// LLEventHost interface +	boost::shared_ptr<LLGestureListener> mListener;  };  #endif diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 162e465fef..cf828306d8 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -875,11 +875,11 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32  	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);  } -class LLChatHandler : public LLCommandHandler +class LLChatCommandHandler : public LLCommandHandler  {  public:  	// not allowed from outside the app -	LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { } +	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }      // Your code here  	bool handle(const LLSD& tokens, const LLSD& query_map, @@ -895,7 +895,7 @@ public:  		{  		S32 channel = tokens[0].asInteger();  			// VWR-19499 Restrict function to chat channels greater than 0. -			if ((channel > 0) && (channel < 2147483647)) +			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))  			{  				retval = true;  		// Send unescaped message, see EXT-6353. @@ -913,6 +913,6 @@ public:  };  // Creating the object registers with the dispatcher. -LLChatHandler gChatHandler; +LLChatCommandHandler gChatHandler; diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llnearbychatbarlistener.cpp new file mode 100644 index 0000000000..0d64eaed47 --- /dev/null +++ b/indra/newview/llnearbychatbarlistener.cpp @@ -0,0 +1,100 @@ +/**
 + * @file   llnearbychatbarlistener.cpp
 + * @author Dave Simmons
 + * @date   2011-03-15
 + * @brief  Implementation for LLNearbyChatBarListener.
 + *
 + * $LicenseInfo:firstyear=2011&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2011, 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 "llnearbychatbarlistener.h"
 +#include "llnearbychatbar.h"
 +
 +#include "llagent.h"
 +#include "llchat.h"
 +
 +
 +
 +LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar)
 +  : LLEventAPI("LLChatBar",
 +               "LLChatBar listener to (e.g.) sendChat, etc."),
 +	mChatbar(chatbar)
 +{
 +    add("sendChat",
 +        "Send chat to the simulator:\n"
 +        "[\"message\"] chat message text [required]\n"
 +        "[\"channel\"] chat channel number [default = 0]\n"
 +		"[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]",
 +        &LLNearbyChatBarListener::sendChat);
 +}
 +
 +
 +// "sendChat" command
 +void LLNearbyChatBarListener::sendChat(LLSD const & chat_data) const
 +{
 +	// Extract the data
 +	std::string chat_text = chat_data["message"].asString();
 +
 +	S32 channel = 0;
 +	if (chat_data.has("channel"))
 +	{
 +		channel = chat_data["channel"].asInteger();
 +		if (channel < 0 || channel >= CHAT_CHANNEL_DEBUG)
 +		{	// Use 0 up to (but not including) CHAT_CHANNEL_DEBUG
 +			channel = 0;
 +		}
 +	}
 +
 +	EChatType type_o_chat = CHAT_TYPE_NORMAL;
 +	if (chat_data.has("type"))
 +	{
 +		std::string type_string = chat_data["type"].asString();
 +		if (type_string == "whisper")
 +		{
 +			type_o_chat = CHAT_TYPE_WHISPER;
 +		}
 +		else if (type_string == "shout")
 +		{
 +			type_o_chat = CHAT_TYPE_SHOUT;
 +		}
 +	}
 +
 +	// Have to prepend /42 style channel numbers
 +	std::string chat_to_send;
 +	if (channel == 0)
 +	{
 +		chat_to_send = chat_text;
 +	}
 +	else
 +	{
 +		chat_to_send += "/";
 +		chat_to_send += chat_data["channel"].asString();
 +		chat_to_send += " ";
 +		chat_to_send += chat_text;
 +	}
 +
 +	// Send it as if it was typed in
 +	mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0));
 +}
 +
 diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llnearbychatbarlistener.h new file mode 100644 index 0000000000..13e4e5990c --- /dev/null +++ b/indra/newview/llnearbychatbarlistener.h @@ -0,0 +1,50 @@ +/**
 + * @file   llnearbychatbarlistener.h
 + * @author Dave Simmons
 + * @date   2011-03-15
 + * @brief  Class definition for LLNearbyChatBarListener.
 + *
 + * $LicenseInfo:firstyear=2011&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2011, 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_LLNEARBYCHATBARLISTENER_H
 +#define LL_LLNEARBYCHATBARLISTENER_H
 +
 +#include "lleventapi.h"
 +
 +class LLSD;
 +class LLNearbyChatBar;
 +
 +class LLNearbyChatBarListener : public LLEventAPI
 +{
 +public:
 +	LLNearbyChatBarListener(LLNearbyChatBar & chatbar);
 +
 +private:
 +    void sendChat(LLSD const & chat_data) const;
 +
 +	LLNearbyChatBar & mChatbar;
 +};
 +
 +#endif // LL_LLNEARBYCHATBARLISTENER_H
 +
 diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index b56fb65a4c..11dc496311 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -441,6 +441,8 @@ void LLNearbyChatScreenChannel::reshape			(S32 width, S32 height, BOOL called_fr  //-----------------------------------------------------------------------------------------------  //LLNearbyChatHandler  //----------------------------------------------------------------------------------------------- +boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat")); +  LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)  {  	mType = type; @@ -487,6 +489,27 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)  		//	tmp_chat.mFromName = tmp_chat.mFromID.asString();  	} +	// Build notification data  +	LLSD notification; +	notification["message"] = chat_msg.mText; +	notification["from"] = chat_msg.mFromName; +	notification["from_id"] = chat_msg.mFromID; +	notification["time"] = chat_msg.mTime; +	notification["source"] = (S32)chat_msg.mSourceType; +	notification["chat_type"] = (S32)chat_msg.mChatType; +	notification["chat_style"] = (S32)chat_msg.mChatStyle; +	// Pass sender info so that it can be rendered properly (STORM-1021). +	notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args); + +	if (chat_msg.mChatType == CHAT_TYPE_DIRECT && +		chat_msg.mText.length() > 0 && +		chat_msg.mText[0] == '@') +	{ +		// Send event on to LLEventStream and exit +		sChatWatcher->post(notification); +		return; +	} +  	// don't show toast and add message to chat history on receive debug message  	// with disabled setting showing script errors or enabled setting to show script  	// errors in separate window. @@ -529,6 +552,10 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)  	} +	// Send event on to LLEventStream +	sChatWatcher->post(notification); + +  	if( nearby_chat->getVisible()  		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT  			&& gSavedSettings.getBOOL("UseChatBubbles") ) @@ -562,25 +589,14 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)  	}  	*/ -	// Add a nearby chat toast. -	LLUUID id; -	id.generate(); -  	LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel); -	  	if(channel)  	{ -		LLSD notification; +		// Add a nearby chat toast. +		LLUUID id; +		id.generate();  		notification["id"] = id; -		notification["message"] = chat_msg.mText; -		notification["from"] = chat_msg.mFromName; -		notification["from_id"] = chat_msg.mFromID; -		notification["time"] = chat_msg.mTime; -		notification["source"] = (S32)chat_msg.mSourceType; -		notification["chat_type"] = (S32)chat_msg.mChatType; -		notification["chat_style"] = (S32)chat_msg.mChatStyle; -		  		std::string r_color_name = "White";  		F32 r_color_alpha = 1.0f;   		LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha); @@ -588,13 +604,8 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)  		notification["text_color"] = r_color_name;  		notification["color_alpha"] = r_color_alpha;  		notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ; - -		// Pass sender info so that it can be rendered properly (STORM-1021). -		notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args); -  		channel->addNotification(notification);	  	} -  }  void LLNearbyChatHandler::onDeleteToast(LLToast* toast) diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h index ec1f29cdfc..b0e4f62d51 100644 --- a/indra/newview/llnearbychathandler.h +++ b/indra/newview/llnearbychathandler.h @@ -29,6 +29,8 @@  #include "llnotificationhandler.h" +class LLEventPump; +  //add LLNearbyChatHandler to LLNotificationsUI namespace  namespace LLNotificationsUI{ @@ -44,6 +46,8 @@ public:  protected:  	virtual void onDeleteToast(LLToast* toast);  	virtual void initChannel(); + +	static boost::scoped_ptr<LLEventPump> sChatWatcher;  };  } diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h index 72fa394621..16e82e4cce 100644 --- a/indra/newview/llnotificationmanager.h +++ b/indra/newview/llnotificationmanager.h @@ -69,7 +69,7 @@ public:  private:  	//TODO (*)  	std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers; -	std::map<std::string, LLChatHandler*> mChatHandlers; +	// cruft std::map<std::string, LLChatHandler*> mChatHandlers;  };  } diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index ddce83c616..ddce83c616 100644..100755 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 29db110523..29db110523 100644..100755 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index fd5c3362bb..fd5c3362bb 100644..100755 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index fca359f51e..fca359f51e 100644..100755 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index ca908ef822..44c9d9a588 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1961,7 +1961,6 @@ bool idle_startup()  		// Start automatic replay if the flag is set.  		if (gSavedSettings.getBOOL("StatsAutoRun") || LLAgentPilot::sReplaySession)  		{ -			LLUUID id;  			LL_DEBUGS("AppInit") << "Starting automatic playback" << LL_ENDL;  			gAgentPilot.startPlayback();  		} diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index b6c0f662e5..319e2508e0 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -54,7 +54,6 @@  #include "llviewerobject.h"  #include "llviewerobjectlist.h"   #include "llviewerregion.h" -#include "llviewerwindow.h"  #include "llvoavatarself.h"  #include "llworld.h" @@ -387,22 +386,7 @@ void LLToolGrab::startGrab()  	mDragStartPointGlobal = grab_start_global;  	mDragStartFromCamera = grab_start_global - gAgentCamera.getCameraPositionGlobal(); -	LLMessageSystem	*msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_ObjectGrab); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -	msg->nextBlockFast(_PREHASH_ObjectData); -	msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID); -	msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset ); -	msg->nextBlock("SurfaceInfo"); -	msg->addVector3("UVCoord", LLVector3(mGrabPick.mUVCoords)); -	msg->addVector3("STCoord", LLVector3(mGrabPick.mSTCoords)); -	msg->addS32Fast(_PREHASH_FaceIndex, mGrabPick.mObjectFace); -	msg->addVector3("Position", mGrabPick.mIntersection); -	msg->addVector3("Normal", mGrabPick.mNormal); -	msg->addVector3("Binormal", mGrabPick.mBinormal); -	msg->sendMessage( objectp->getRegion()->getHost()); +	send_ObjectGrab_message(objectp, mGrabPick, grab_offset);  	mGrabOffsetFromCenterInitial = grab_offset;  	mGrabHiddenOffsetFromCamera = mDragStartFromCamera; @@ -1036,28 +1020,12 @@ void LLToolGrab::stopGrab()  	}  	// Next, send messages to simulator -	LLMessageSystem *msg = gMessageSystem;  	switch(mMode)  	{  	case GRAB_ACTIVE_CENTER:  	case GRAB_NONPHYSICAL:  	case GRAB_LOCKED: -		msg->newMessageFast(_PREHASH_ObjectDeGrab); -		msg->nextBlockFast(_PREHASH_AgentData); -		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -		msg->nextBlockFast(_PREHASH_ObjectData); -		msg->addU32Fast(_PREHASH_LocalID, objectp->mLocalID); -		msg->nextBlock("SurfaceInfo"); -		msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); -		msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); -		msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); -		msg->addVector3("Position", pick.mIntersection); -		msg->addVector3("Normal", pick.mNormal); -		msg->addVector3("Binormal", pick.mBinormal); - -		msg->sendMessage(objectp->getRegion()->getHost()); - +		send_ObjectDeGrab_message(objectp, pick);  		mVerticalDragging = FALSE;  		break; @@ -1109,3 +1077,66 @@ LLVector3d LLToolGrab::getGrabPointGlobal()  		return gAgent.getPositionGlobal();  	}  } + + +void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, const LLVector3 &grab_offset) +{ +	if (!object) return; + +	LLMessageSystem	*msg = gMessageSystem; + +	msg->newMessageFast(_PREHASH_ObjectGrab); +	msg->nextBlockFast( _PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	msg->nextBlockFast( _PREHASH_ObjectData); +	msg->addU32Fast(    _PREHASH_LocalID, object->mLocalID); +	msg->addVector3Fast(_PREHASH_GrabOffset, grab_offset); +	msg->nextBlock("SurfaceInfo"); +	msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); +	msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); +	msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); +	msg->addVector3("Position", pick.mIntersection); +	msg->addVector3("Normal", pick.mNormal); +	msg->addVector3("Binormal", pick.mBinormal); +	msg->sendMessage( object->getRegion()->getHost()); + +	/*  Diagnostic code +	llinfos << "mUVCoords: " << pick.mUVCoords +			<< ", mSTCoords: " << pick.mSTCoords +			<< ", mObjectFace: " << pick.mObjectFace +			<< ", mIntersection: " << pick.mIntersection +			<< ", mNormal: " << pick.mNormal +			<< ", mBinormal: " << pick.mBinormal +			<< llendl; + +	llinfos << "Avatar pos: " << gAgent.getPositionAgent() << llendl; +	llinfos << "Object pos: " << object->getPosition() << llendl; +	*/ +} + + +void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick) +{ +	if (!object) return; + +	LLMessageSystem	*msg = gMessageSystem; + +	msg->newMessageFast(_PREHASH_ObjectDeGrab); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	msg->nextBlockFast(_PREHASH_ObjectData); +	msg->addU32Fast(_PREHASH_LocalID, object->mLocalID); +	msg->nextBlock("SurfaceInfo"); +	msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); +	msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); +	msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); +	msg->addVector3("Position", pick.mIntersection); +	msg->addVector3("Normal", pick.mNormal); +	msg->addVector3("Binormal", pick.mBinormal); +	msg->sendMessage(object->getRegion()->getHost()); +} + + + diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index 61e3fcb8b2..06a3b662c8 100644 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -39,6 +39,13 @@ class LLTextBox;  class LLViewerObject;  class LLPickInfo; + +// Message utilities +void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, const LLVector3 &grab_offset); +void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick); + + +  class LLToolGrab : public LLTool, public LLSingleton<LLToolGrab>  {  public: diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index 286b16bab2..86a29de403 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -77,6 +77,10 @@ void LLViewerChat::getChatColor(const LLChat& chat, LLColor4& r_color)  				{  					r_color = LLUIColorTable::instance().getColor("llOwnerSayChatColor");  				} +				else if ( chat.mChatType == CHAT_TYPE_DIRECT ) +				{ +					r_color = LLUIColorTable::instance().getColor("DirectChatColor"); +				}  				else  				{  					r_color = LLUIColorTable::instance().getColor("ObjectChatColor"); @@ -142,6 +146,10 @@ void LLViewerChat::getChatColor(const LLChat& chat, std::string& r_color_name, F  				{  					r_color_name = "llOwnerSayChatColor";  				} +				else if ( chat.mChatType == CHAT_TYPE_DIRECT ) +				{ +					r_color_name = "DirectChatColor"; +				}  				else  				{  					r_color_name = "ObjectChatColor"; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5a3baf2650..ea6ccb7792 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -104,6 +104,7 @@  #include "llappearancemgr.h"  #include "lltrans.h"  #include "lleconomy.h" +#include "lltoolgrab.h"  #include "boost/unordered_map.hpp"  using namespace LLVOAvatarDefines; @@ -2388,50 +2389,23 @@ class LLObjectEnableReportAbuse : public view_listener_t  	}  }; +  void handle_object_touch()  { -		LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); -		if (!object) return; - -		LLPickInfo pick = LLToolPie::getInstance()->getPick(); +	LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); +	if (!object) return; -		LLMessageSystem	*msg = gMessageSystem; +	LLPickInfo pick = LLToolPie::getInstance()->getPick(); -		msg->newMessageFast(_PREHASH_ObjectGrab); -		msg->nextBlockFast( _PREHASH_AgentData); -		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -		msg->nextBlockFast( _PREHASH_ObjectData); -		msg->addU32Fast(    _PREHASH_LocalID, object->mLocalID); -		msg->addVector3Fast(_PREHASH_GrabOffset, LLVector3::zero ); -		msg->nextBlock("SurfaceInfo"); -		msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); -		msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); -		msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); -		msg->addVector3("Position", pick.mIntersection); -		msg->addVector3("Normal", pick.mNormal); -		msg->addVector3("Binormal", pick.mBinormal); -		msg->sendMessage( object->getRegion()->getHost()); - -		// *NOTE: Hope the packets arrive safely and in order or else -		// there will be some problems. -		// *TODO: Just fix this bad assumption. -		msg->newMessageFast(_PREHASH_ObjectDeGrab); -		msg->nextBlockFast(_PREHASH_AgentData); -		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -		msg->nextBlockFast(_PREHASH_ObjectData); -		msg->addU32Fast(_PREHASH_LocalID, object->mLocalID); -		msg->nextBlock("SurfaceInfo"); -		msg->addVector3("UVCoord", LLVector3(pick.mUVCoords)); -		msg->addVector3("STCoord", LLVector3(pick.mSTCoords)); -		msg->addS32Fast(_PREHASH_FaceIndex, pick.mObjectFace); -		msg->addVector3("Position", pick.mIntersection); -		msg->addVector3("Normal", pick.mNormal); -		msg->addVector3("Binormal", pick.mBinormal); -		msg->sendMessage(object->getRegion()->getHost()); +	// *NOTE: Hope the packets arrive safely and in order or else +	// there will be some problems. +	// *TODO: Just fix this bad assumption. +	send_ObjectGrab_message(object, pick, LLVector3::zero); +	send_ObjectDeGrab_message(object, pick);  } + +  static void init_default_item_label(const std::string& item_name)  {  	boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 9641a0901c..5792bf2c03 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3202,7 +3202,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  	if (is_audible)  	{  		BOOL visible_in_chat_bubble = FALSE; -		std::string verb;  		color.setVec(1.f,1.f,1.f,1.f);  		msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg); @@ -3251,18 +3250,19 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  		}  		else  		{ +			chat.mText = "";  			switch(chat.mChatType)  			{  			case CHAT_TYPE_WHISPER: -				verb = LLTrans::getString("whisper") + " "; +				chat.mText = LLTrans::getString("whisper") + " ";  				break;  			case CHAT_TYPE_DEBUG_MSG:  			case CHAT_TYPE_OWNER:  			case CHAT_TYPE_NORMAL: -				verb = ""; +			case CHAT_TYPE_DIRECT:  				break;  			case CHAT_TYPE_SHOUT: -				verb = LLTrans::getString("shout") + " "; +				chat.mText = LLTrans::getString("shout") + " ";  				break;  			case CHAT_TYPE_START:  			case CHAT_TYPE_STOP: @@ -3270,13 +3270,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  				break;  			default:  				LL_WARNS("Messaging") << "Unknown type " << chat.mChatType << " in chat!" << LL_ENDL; -				verb = "";  				break;  			} - -			chat.mText = ""; -			chat.mText += verb;  			chat.mText += mesg;  		} diff --git a/indra/newview/llwearabletype.cpp b/indra/newview/llwearabletype.cpp index f933be4d8f..5b4b820903 100644 --- a/indra/newview/llwearabletype.cpp +++ b/indra/newview/llwearabletype.cpp @@ -144,6 +144,7 @@ BOOL LLWearableType::getDisableCameraSwitch(LLWearableType::EType type)  {  	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();  	const WearableEntry *entry = dict->lookup(type); +	if (!entry)	return FALSE;  	return entry->mDisableCameraSwitch;  } @@ -152,6 +153,7 @@ BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type)  {  	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();  	const WearableEntry *entry = dict->lookup(type); +	if (!entry)	return FALSE;  	return entry->mAllowMultiwear;  } diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 72a4dd7f63..8494ce8b1b 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -760,4 +760,7 @@      <color       name="MenuBarProjectBgColor"       reference="MdBlue" /> +    <color +     name="DirectChatColor" +     reference="LtOrange" />  </colors> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 318bc9251f..f83b2e3d9c 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5227,6 +5227,20 @@ Insufficient permissions to rez object.    <notification     icon="notifytip.tga" +   name="IMAcrossParentEstates" +   type="notifytip"> +Unable to send IM across parent estates. +  </notification> + +  <notification +   icon="notifytip.tga" +   name="TransferInventoryAcrossParentEstates" +   type="notifytip"> +Unable to transfer inventory across parent estates. +  </notification> + +  <notification +   icon="notifytip.tga"     name="UnableToLoadNotecard"     type="notifytip">  Unable to load notecard. diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml index 8a37822413..c6d1e38ee7 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml @@ -208,6 +208,37 @@    </text>    <color_swatch     can_apply_immediately="true" +   color="LtOrange" +   follows="left|top" +   height="24" +   label_height="0" +   layout="topleft" +   left="360" +   name="direct" +   top_pad="-15" +   width="44" > +    <color_swatch.init_callback +		 function="Pref.getUIColor" +		 parameter="DirectChatColor" /> +    <color_swatch.commit_callback +		 function="Pref.applyUIColor" +		 parameter="DirectChatColor" /> +  </color_swatch> +  <text +   type="string" +   length="1" +   follows="left|top" +   height="10" +   layout="topleft" +   left_pad="5" +   mouse_opaque="false" +   name="text_box10" +   top_delta="5" +   width="95"> +    Direct +  </text> +  <color_swatch +   can_apply_immediately="true"     color="LtYellow"     follows="left|top"     height="24" diff --git a/scripts/md5check.py b/scripts/md5check.py index 1a54a2844c..1a54a2844c 100644..100755 --- a/scripts/md5check.py +++ b/scripts/md5check.py | 
