From 74772a1f61f486035cb716ca9b62f7a626a54b75 Mon Sep 17 00:00:00 2001 From: Latif Khalifa Date: Tue, 14 Aug 2012 19:30:49 +0200 Subject: [PATCH] One should never invoke CAPs request without checking if the capability is present. Fixes setting home location on OSGrid, issue #426 --- indra/newview/llagent.cpp | 81 ++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 5f0539b7c..d93f23226 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2161,38 +2161,65 @@ void LLAgent::setStartPosition( U32 location_id ) agent_pos.mV[VZ] = llclamp( agent_pos.mV[VZ], mRegionp->getLandHeightRegion( agent_pos ), LLWorld::getInstance()->getRegionMaxHeight() ); - // Send the CapReq - LLSD request; - LLSD body; - LLSD homeLocation; - homeLocation["LocationId"] = LLSD::Integer(location_id); - homeLocation["LocationPos"] = ll_sdmap_from_vector3(agent_pos); - homeLocation["LocationLookAt"] = ll_sdmap_from_vector3(mFrameAgent.getAtAxis()); + // Do we have HomeLocation capability? + std::string capURL = gAgent.getRegion()->getCapability("HomeLocation"); - body["HomeLocation"] = homeLocation; + if ( capURL.empty() ) + { + // Send UDP message about the new location + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_SetStartLocationRequest); + msg->nextBlockFast( _PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, getID()); + msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + msg->nextBlockFast( _PREHASH_StartLocationData); + // corrected by sim + msg->addStringFast(_PREHASH_SimName, ""); + msg->addU32Fast(_PREHASH_LocationID, location_id); + msg->addVector3Fast(_PREHASH_LocationPos, agent_pos); + msg->addVector3Fast(_PREHASH_LocationLookAt,mFrameAgent.getAtAxis()); + + // Reliable only helps when setting home location. Last + // location is sent on quit, and we don't have time to ack + // the packets. + msg->sendReliable(mRegionp->getHost()); + } + else + { + // Send the CapReq + LLSD request; + LLSD body; + LLSD homeLocation; - // This awkward idiom warrants explanation. - // For starters, LLSDMessage::ResponderAdapter is ONLY for testing the new - // LLSDMessage functionality with a pre-existing LLHTTPClient::Responder. - // In new code, define your reply/error methods on the same class as the - // sending method, bind them to local LLEventPump objects and pass those - // LLEventPump names in the request LLSD object. - // When testing old code, the new LLHomeLocationResponder object - // is referenced by an LLHTTPClient::ResponderPtr, so when the - // ResponderAdapter is deleted, the LLHomeLocationResponder will be too. - // We must trust that the underlying LLHTTPClient code will eventually - // fire either the reply callback or the error callback; either will cause - // the ResponderAdapter to delete itself. - LLSDMessage::ResponderAdapter* - adapter(new LLSDMessage::ResponderAdapter(new LLHomeLocationResponder())); + homeLocation["LocationId"] = LLSD::Integer(location_id); + homeLocation["LocationPos"] = ll_sdmap_from_vector3(agent_pos); + homeLocation["LocationLookAt"] = ll_sdmap_from_vector3(mFrameAgent.getAtAxis()); - request["message"] = "HomeLocation"; - request["payload"] = body; - request["reply"] = adapter->getReplyName(); - request["error"] = adapter->getErrorName(); + body["HomeLocation"] = homeLocation; - gAgent.getRegion()->getCapAPI().post(request); + // This awkward idiom warrants explanation. + // For starters, LLSDMessage::ResponderAdapter is ONLY for testing the new + // LLSDMessage functionality with a pre-existing LLHTTPClient::Responder. + // In new code, define your reply/error methods on the same class as the + // sending method, bind them to local LLEventPump objects and pass those + // LLEventPump names in the request LLSD object. + // When testing old code, the new LLHomeLocationResponder object + // is referenced by an LLHTTPClient::ResponderPtr, so when the + // ResponderAdapter is deleted, the LLHomeLocationResponder will be too. + // We must trust that the underlying LLHTTPClient code will eventually + // fire either the reply callback or the error callback; either will cause + // the ResponderAdapter to delete itself. + LLSDMessage::ResponderAdapter* + adapter(new LLSDMessage::ResponderAdapter(new LLHomeLocationResponder())); + + request["message"] = "HomeLocation"; + request["payload"] = body; + request["reply"] = adapter->getReplyName(); + request["error"] = adapter->getErrorName(); + + gAgent.getRegion()->getCapAPI().post(request); + } const U32 HOME_INDEX = 1; if( HOME_INDEX == location_id )