Renamed AICurlInterface::Responder to AICurlInterface::ResponderBase, but without the virtual 'event' methods. Derived from that: Responder and ReponderWithCompleted, where the first defines result = 0, ErrorWithContent and error, and the latter completedRaw and completed. Added HttpClient::IgnoreBody, derived from Responder and implementing 'result' doing nothing; HttpClient::Ignore is now derived from IgnoreBody and defines the still pure virtual getHTTPTimeoutPolicy. Added ResponderBase::decode_body, which is now the sole place where the code makes the decision wether some response data might be LLSD or not based on the http status result. Before it just tried to decode everything as LLSD, which seems a bit nonsense. ResponderWithCompleted::completed no longer does anything, since classes derived from ResponderWithCompleted are expected to override it, or never call it by overriding completedRaw. Entry point is now ResponderBase::finished = 0, instead of completedRaw, where ResponderWithCompleted implements finished by called completedRaw, but Responder doesn't: that directly calls result/errorWithContent/error. Or, for the hack ResponderAdapter, the entry points are pubResult/pubErrorWithContent. Those are now the ONLY public methods, so more confusion. mFinished is now set in all cases. As a result of all that, it is no longer possible to accidently pass a responder to ResponderAdapter that would break because it expects completed() and completedRaw() to be called. Added LLBufferArray::writeChannelTo. Fixed bug for BlockingResponder::body (returned reference to temporary). LLSDMessage::ResponderAdapter now allows a "timeoutpolicy" name to be passed (not doing so results in the default timings), so that the timeout policy of the used responder is retained. Fixed llfasttimerview.cpp to test LLSDSerialize::fromXML() to return a positive value instead of non-zero, because it may return -1 when the parsing fails (three places). Removed LLHTTPClient::Responder as base class from LLFloaterRegionDebugConsole completely: it isn't a responder! Several other responder classes were simplified a bit in order to compile again with the above changes.
214 lines
6.3 KiB
C++
214 lines
6.3 KiB
C++
/**
|
|
* @file llviewerdisplayname.cpp
|
|
* @brief Wrapper for display name functionality
|
|
*
|
|
* $LicenseInfo:firstyear=2010&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 "llviewerdisplayname.h"
|
|
|
|
// viewer includes
|
|
#include "llagent.h"
|
|
#include "llviewerregion.h"
|
|
#include "llvoavatar.h"
|
|
|
|
// library includes
|
|
#include "llavatarnamecache.h"
|
|
#include "llhttpclient.h"
|
|
#include "llhttpnode.h"
|
|
#include "llnotificationsutil.h"
|
|
#include "llui.h" // getLanguage()
|
|
|
|
class AIHTTPTimeoutPolicy;
|
|
extern AIHTTPTimeoutPolicy setDisplayNameResponder_timeout;
|
|
|
|
namespace LLViewerDisplayName
|
|
{
|
|
// Fired when viewer receives server response to display name change
|
|
set_name_signal_t sSetDisplayNameSignal;
|
|
|
|
// Fired when there is a change in the agent's name
|
|
name_changed_signal_t sNameChangedSignal;
|
|
|
|
void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)
|
|
{
|
|
sNameChangedSignal.connect(cb);
|
|
}
|
|
|
|
}
|
|
|
|
class LLSetDisplayNameResponder : public LLHTTPClient::ResponderIgnoreBody
|
|
{
|
|
public:
|
|
// only care about errors
|
|
/*virtual*/ void error(U32 status, const std::string& reason)
|
|
{
|
|
LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
|
|
LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
|
|
}
|
|
|
|
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return setDisplayNameResponder_timeout; }
|
|
};
|
|
|
|
void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
|
|
{
|
|
// TODO: simple validation here
|
|
|
|
LLViewerRegion* region = gAgent.getRegion();
|
|
llassert(region);
|
|
std::string cap_url = region->getCapability("SetDisplayName");
|
|
if (cap_url.empty())
|
|
{
|
|
// this server does not support display names, report error
|
|
slot(false, "unsupported", LLSD());
|
|
return;
|
|
}
|
|
|
|
// People API can return localized error messages. Indicate our
|
|
// language preference via header.
|
|
AIHTTPHeaders headers("Accept-Language", LLUI::getLanguage());
|
|
|
|
// People API requires both the old and new value to change a variable.
|
|
// Our display name will be in cache before the viewer's UI is available
|
|
// to request a change, so we can use direct lookup without callback.
|
|
LLAvatarName av_name;
|
|
if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
|
|
{
|
|
slot(false, "name unavailable", LLSD());
|
|
return;
|
|
}
|
|
|
|
// People API expects array of [ "old value", "new value" ]
|
|
LLSD change_array = LLSD::emptyArray();
|
|
change_array.append(av_name.mDisplayName);
|
|
change_array.append(display_name);
|
|
|
|
llinfos << "Set name POST to " << cap_url << llendl;
|
|
|
|
// Record our caller for when the server sends back a reply
|
|
sSetDisplayNameSignal.connect(slot);
|
|
|
|
// POST the requested change. The sim will not send a response back to
|
|
// this request directly, rather it will send a separate message after it
|
|
// communicates with the back-end.
|
|
LLSD body;
|
|
body["display_name"] = change_array;
|
|
LLHTTPClient::post4(cap_url, body, new LLSetDisplayNameResponder, headers);
|
|
}
|
|
|
|
class LLSetDisplayNameReply : public LLHTTPNode
|
|
{
|
|
LOG_CLASS(LLSetDisplayNameReply);
|
|
public:
|
|
/*virtual*/ void post(
|
|
LLHTTPNode::ResponsePtr response,
|
|
const LLSD& context,
|
|
const LLSD& input) const
|
|
{
|
|
LLSD body = input["body"];
|
|
|
|
S32 status = body["status"].asInteger();
|
|
bool success = (status == 200);
|
|
std::string reason = body["reason"].asString();
|
|
LLSD content = body["content"];
|
|
|
|
llinfos << "status " << status << " reason " << reason << llendl;
|
|
|
|
// If viewer's concept of display name is out-of-date, the set request
|
|
// will fail with 409 Conflict. If that happens, fetch up-to-date
|
|
// name information.
|
|
if (status == 409)
|
|
{
|
|
LLUUID agent_id = gAgent.getID();
|
|
// Flush stale data
|
|
LLAvatarNameCache::erase( agent_id );
|
|
// Queue request for new data
|
|
LLAvatarName ignored;
|
|
LLAvatarNameCache::get( agent_id, &ignored );
|
|
// Kill name tag, as it is wrong
|
|
LLVOAvatar::invalidateNameTag( agent_id );
|
|
}
|
|
|
|
// inform caller of result
|
|
LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
|
|
LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
|
|
}
|
|
};
|
|
|
|
|
|
class LLDisplayNameUpdate : public LLHTTPNode
|
|
{
|
|
|
|
/*virtual*/ void post(
|
|
LLHTTPNode::ResponsePtr response,
|
|
const LLSD& context,
|
|
const LLSD& input) const
|
|
{
|
|
LLSD body = input["body"];
|
|
LLUUID agent_id = body["agent_id"];
|
|
std::string old_display_name = body["old_display_name"];
|
|
// By convention this record is called "agent" in the People API
|
|
LLSD name_data = body["agent"];
|
|
|
|
// Inject the new name data into cache
|
|
LLAvatarName av_name;
|
|
av_name.fromLLSD( name_data );
|
|
|
|
llinfos << "name-update now " << LLDate::now()
|
|
<< " next_update " << LLDate(av_name.mNextUpdate)
|
|
<< llendl;
|
|
|
|
// Name expiration time may be provided in headers, or we may use a
|
|
// default value
|
|
// *TODO: get actual headers out of ResponsePtr
|
|
//LLSD headers = response->mHeaders;
|
|
av_name.mExpires =
|
|
LLAvatarNameCache::nameExpirationFromHeaders(AIHTTPReceivedHeaders());
|
|
|
|
LLAvatarNameCache::insert(agent_id, av_name);
|
|
|
|
// force name tag to update
|
|
LLVOAvatar::invalidateNameTag(agent_id);
|
|
|
|
LLSD args;
|
|
args["OLD_NAME"] = old_display_name;
|
|
args["SLID"] = av_name.mUsername;
|
|
args["NEW_NAME"] = av_name.mDisplayName;
|
|
LLNotificationsUtil::add("DisplayNameUpdate", args);
|
|
if (agent_id == gAgent.getID())
|
|
{
|
|
LLViewerDisplayName::sNameChangedSignal();
|
|
}
|
|
}
|
|
};
|
|
|
|
LLHTTPRegistration<LLSetDisplayNameReply>
|
|
gHTTPRegistrationMessageSetDisplayNameReply(
|
|
"/message/SetDisplayNameReply");
|
|
|
|
LLHTTPRegistration<LLDisplayNameUpdate>
|
|
gHTTPRegistrationMessageDisplayNameUpdate(
|
|
"/message/DisplayNameUpdate");
|
|
|