Merge branch 'master' of git://github.com/siana/SingularityViewer.git

Conflicts:
	indra/llrender/llglstates.h
This commit is contained in:
Shyotl
2011-03-25 17:54:52 -05:00
25 changed files with 1298 additions and 152 deletions

View File

@@ -599,3 +599,8 @@ bool LLHTTPClient::hasPump()
{ {
return theClientPump != NULL; return theClientPump != NULL;
} }
LLPumpIO &LLHTTPClient::getPump()
{
return *theClientPump;
}

View File

@@ -156,6 +156,8 @@ public:
///< must be called before any of the above calls are made ///< must be called before any of the above calls are made
static bool hasPump(); static bool hasPump();
///< for testing ///< for testing
static LLPumpIO &getPump();
///< Hippo special
}; };
#endif // LL_LLHTTPCLIENT_H #endif // LL_LLHTTPCLIENT_H

View File

@@ -2,31 +2,25 @@
* @file llglstates.h * @file llglstates.h
* @brief LLGL states definitions * @brief LLGL states definitions
* *
* $LicenseInfo:firstyear=2001&license=viewergpl$ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code * Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab * Copyright (C) 2010, Linden Research, Inc.
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* *
* There are special exceptions to the terms and conditions of the GPL as * This library is free software; you can redistribute it and/or
* it is applied to this Source Code. View the full text of the exception * modify it under the terms of the GNU Lesser General Public
* in the file doc/FLOSS-exception.txt in this software distribution, or * License as published by the Free Software Foundation;
* online at * version 2.1 of the License only.
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* *
* By copying, modifying or distributing this software, you acknowledge * This library is distributed in the hope that it will be useful,
* that you have read and understood your obligations described above, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* and agree to abide by those obligations. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* *
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * You should have received a copy of the GNU Lesser General Public
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * License along with this library; if not, write to the Free Software
* COMPLETENESS OR PERFORMANCE. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
@@ -47,6 +41,7 @@ public:
~LLGLDepthTest(); ~LLGLDepthTest();
void checkState(); void checkState();
GLboolean mPrevDepthEnabled; GLboolean mPrevDepthEnabled;
GLenum mPrevDepthFunc; GLenum mPrevDepthFunc;
GLboolean mPrevWriteEnabled; GLboolean mPrevWriteEnabled;

View File

@@ -225,6 +225,16 @@ bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNo
} }
bool LLUICtrlFactory::getLayeredXMLNodeFromBuffer(const std::string &buffer, LLXMLNodePtr& root)
{
if (!LLXMLNode::parseBuffer(buffer.data(), buffer.size(), root, 0)) {
llwarns << "Error reading UI description from buffer." << llendl;
return false;
}
return true;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// buildFloater() // buildFloater()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -238,6 +248,23 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen
return; return;
} }
buildFloaterInternal(floaterp, root, filename, factory_map, open);
}
void LLUICtrlFactory::buildFloaterFromBuffer(LLFloater *floaterp, const std::string &buffer,
const LLCallbackMap::map_t *factory_map, BOOL open) /* Flawfinder: ignore */
{
LLXMLNodePtr root;
if (!LLUICtrlFactory::getLayeredXMLNodeFromBuffer(buffer, root))
return;
buildFloaterInternal(floaterp, root, "(buffer)", factory_map, open);
}
void LLUICtrlFactory::buildFloaterInternal(LLFloater *floaterp, LLXMLNodePtr &root, const std::string &filename,
const LLCallbackMap::map_t *factory_map, BOOL open) /* Flawfinder: ignore */
{
// root must be called floater // root must be called floater
if( !(root->hasName("floater") || root->hasName("multi_floater") ) ) if( !(root->hasName("floater") || root->hasName("multi_floater") ) )
{ {
@@ -294,14 +321,32 @@ S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename)
BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename,
const LLCallbackMap::map_t* factory_map) const LLCallbackMap::map_t* factory_map)
{ {
BOOL didPost = FALSE;
LLXMLNodePtr root; LLXMLNodePtr root;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) if (!LLUICtrlFactory::getLayeredXMLNode(filename, root))
{ {
return didPost; return FALSE;
} }
return buildPanelInternal(panelp, root, filename, factory_map);
}
BOOL LLUICtrlFactory::buildPanelFromBuffer(LLPanel *panelp, const std::string &buffer,
const LLCallbackMap::map_t* factory_map)
{
LLXMLNodePtr root;
if (!LLUICtrlFactory::getLayeredXMLNodeFromBuffer(buffer, root))
return FALSE;
return buildPanelInternal(panelp, root, "(buffer)", factory_map);
}
BOOL LLUICtrlFactory::buildPanelInternal(LLPanel* panelp, LLXMLNodePtr &root, const std::string &filename,
const LLCallbackMap::map_t* factory_map)
{
BOOL didPost = FALSE;
// root must be called panel // root must be called panel
if( !root->hasName("panel" ) ) if( !root->hasName("panel" ) )
{ {

View File

@@ -53,8 +53,12 @@ public:
void buildFloater(LLFloater* floaterp, const std::string &filename, void buildFloater(LLFloater* floaterp, const std::string &filename,
const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE);
void buildFloaterFromBuffer(LLFloater *floaterp, const std::string &buffer,
const LLCallbackMap::map_t *factory_map = NULL, BOOL open = TRUE);
BOOL buildPanel(LLPanel* panelp, const std::string &filename, BOOL buildPanel(LLPanel* panelp, const std::string &filename,
const LLCallbackMap::map_t* factory_map = NULL); const LLCallbackMap::map_t* factory_map = NULL);
BOOL buildPanelFromBuffer(LLPanel *panelp, const std::string &buffer,
const LLCallbackMap::map_t* factory_map = NULL);
void removePanel(LLPanel* panelp) { mBuiltPanels.erase(panelp->getHandle()); } void removePanel(LLPanel* panelp) { mBuiltPanels.erase(panelp->getHandle()); }
void removeFloater(LLFloater* floaterp) { mBuiltFloaters.erase(floaterp->getHandle()); } void removeFloater(LLFloater* floaterp) { mBuiltFloaters.erase(floaterp->getHandle()); }
@@ -77,6 +81,7 @@ public:
virtual LLView* createWidget(LLPanel *parent, LLXMLNodePtr node); virtual LLView* createWidget(LLPanel *parent, LLXMLNodePtr node);
static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
static bool getLayeredXMLNodeFromBuffer(const std::string &buffer, LLXMLNodePtr& root);
static const std::vector<std::string>& getXUIPaths(); static const std::vector<std::string>& getXUIPaths();
@@ -94,6 +99,11 @@ private:
static std::vector<std::string> sXUIPaths; static std::vector<std::string> sXUIPaths;
LLPanel* mDummyPanel; LLPanel* mDummyPanel;
void buildFloaterInternal(LLFloater *floaterp, LLXMLNodePtr &root, const std::string &filename,
const LLCallbackMap::map_t *factory_map, BOOL open);
BOOL buildPanelInternal(LLPanel* panelp, LLXMLNodePtr &root, const std::string &filename,
const LLCallbackMap::map_t* factory_map = NULL);
}; };

View File

@@ -677,7 +677,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML
U32 length = ftell(fp); U32 length = ftell(fp);
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
U8* buffer = new U8[length+1]; char *buffer = new char[length+1];
size_t nread = fread(buffer, 1, length, fp); size_t nread = fread(buffer, 1, length, fp);
buffer[nread] = 0; buffer[nread] = 0;
fclose(fp); fclose(fp);
@@ -689,7 +689,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML
// static // static
bool LLXMLNode::parseBuffer( bool LLXMLNode::parseBuffer(
U8* buffer, const char *buffer,
U32 length, U32 length,
LLXMLNodePtr& node, LLXMLNodePtr& node,
LLXMLNode* defaults) LLXMLNode* defaults)
@@ -708,7 +708,7 @@ bool LLXMLNode::parseBuffer(
XML_SetUserData(my_parser, (void *)file_node_ptr); XML_SetUserData(my_parser, (void *)file_node_ptr);
// Do the parsing // Do the parsing
if (XML_Parse(my_parser, (const char *)buffer, length, TRUE) != XML_STATUS_OK) if (XML_Parse(my_parser, buffer, length, TRUE) != XML_STATUS_OK)
{ {
llwarns << "Error parsing xml error code: " llwarns << "Error parsing xml error code: "
<< XML_ErrorString(XML_GetErrorCode(my_parser)) << XML_ErrorString(XML_GetErrorCode(my_parser))

View File

@@ -141,7 +141,7 @@ public:
LLXMLNodePtr& node, LLXMLNodePtr& node,
LLXMLNode* defaults_tree); LLXMLNode* defaults_tree);
static bool parseBuffer( static bool parseBuffer(
U8* buffer, const char *buffer,
U32 length, U32 length,
LLXMLNodePtr& node, LLXMLNodePtr& node,
LLXMLNode* defaults); LLXMLNode* defaults);

View File

@@ -50,6 +50,7 @@ LLStdStringTable LLXmlTree::sAttributeKeys(1024);
LLXmlTree::LLXmlTree() LLXmlTree::LLXmlTree()
: mRoot( NULL ), : mRoot( NULL ),
mParser(0),
mNodeNames(512) mNodeNames(512)
{ {
} }
@@ -83,6 +84,39 @@ BOOL LLXmlTree::parseFile(const std::string &path, BOOL keep_contents)
return success; return success;
} }
bool LLXmlTree::parseBufferStart(bool keep_contents)
{
if (mRoot) delete mRoot;
mRoot = NULL;
if (mParser) delete mParser;
mParser = new LLXmlTreeParser(this);
mParser->parseBufferStart(keep_contents);
return (mParser != 0);
}
bool LLXmlTree::parseBuffer(const char *buf, int len)
{
bool success = mParser->parseBuffer(buf, len);
if (!success) {
S32 line_number = mParser->getCurrentLineNumber();
const char* error = mParser->getErrorString();
llwarns << "LLXmlTree parse failed in line " << line_number << ": " << error << llendl;
delete mParser;
mParser = 0;
}
return success;
}
bool LLXmlTree::parseBufferFinalize()
{
bool success = mParser->parseBufferFinalize(&mRoot);
delete mParser;
mParser = 0;
return success;
}
void LLXmlTree::dump() void LLXmlTree::dump()
{ {
if( mRoot ) if( mRoot )
@@ -102,6 +136,25 @@ void LLXmlTree::dumpNode( LLXmlTreeNode* node, const std::string& prefix )
} }
} }
void LLXmlTree::write(std::string &buffer) const
{
if (mRoot) writeNode(mRoot, buffer, "");
}
void LLXmlTree::writeNode(LLXmlTreeNode *node, std::string &buffer, const std::string &indent) const
{
if (!node->getFirstChild()) {
node->writeNoChild(buffer, indent);
} else {
node->writeStart(buffer, indent);
std::string newIndent = indent + " ";
for (LLXmlTreeNode *child=node->getFirstChild(); child; child=node->getNextChild())
writeNode(child, buffer, newIndent);
node->writeEnd(buffer, indent);
}
}
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// LLXmlTreeNode // LLXmlTreeNode
@@ -139,6 +192,43 @@ void LLXmlTreeNode::dump( const std::string& prefix )
llcont << llendl; llcont << llendl;
} }
void LLXmlTreeNode::writeNoChild(std::string &buffer, const std::string &indent) const
{
if (!mContents.empty()) {
writeStart(buffer, indent);
writeEnd(buffer, indent);
} else {
buffer += indent + '<' + mName;
writeAttributes(buffer);
buffer += "/>\n";
}
}
void LLXmlTreeNode::writeStart(std::string &buffer, const std::string &indent) const
{
buffer += indent + '<' + mName;
writeAttributes(buffer);
buffer += ">\n";
}
void LLXmlTreeNode::writeEnd(std::string &buffer, const std::string &indent) const
{
if (!mContents.empty()) {
buffer += indent + " " + mContents + '\n';
}
buffer += indent + "</" + mName + ">\n";
}
void LLXmlTreeNode::writeAttributes(std::string &buffer) const
{
attribute_map_t::const_iterator it, end = mAttributes.end();
for (it=mAttributes.begin(); it!=end; ++it) {
LLStdStringHandle key = it->first;
const std::string *value = it->second;
buffer += ' ' + *key + "=\"" + *value + '"';
}
}
BOOL LLXmlTreeNode::hasAttribute(const std::string& name) BOOL LLXmlTreeNode::hasAttribute(const std::string& name)
{ {
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
@@ -528,7 +618,7 @@ BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, B
BOOL success = LLXmlParser::parseFile(path); BOOL success = LLXmlParser::parseFile(path);
*root = mRoot; if (root) *root = mRoot;
mRoot = NULL; mRoot = NULL;
if( success ) if( success )
@@ -540,6 +630,31 @@ BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, B
return success; return success;
} }
void LLXmlTreeParser::parseBufferStart(BOOL keep_contents)
{
llassert(!mRoot);
llassert(!mCurrent);
mKeepContents = keep_contents;
}
bool LLXmlTreeParser::parseBuffer(const char *buf, int len)
{
return (LLXmlParser::parse(buf, len, false) != 0);
}
bool LLXmlTreeParser::parseBufferFinalize(LLXmlTreeNode** root)
{
bool success = (LLXmlParser::parse(0, 0, true) != 0);
if (root) *root = mRoot;
mRoot = NULL;
llassert(!success || !mCurrent);
mCurrent = NULL;
return success;
}
const std::string& LLXmlTreeParser::tabs() const std::string& LLXmlTreeParser::tabs()
{ {

View File

@@ -63,11 +63,18 @@ public:
virtual BOOL parseFile(const std::string &path, BOOL keep_contents = TRUE); virtual BOOL parseFile(const std::string &path, BOOL keep_contents = TRUE);
bool parseBufferStart(bool keep_contents = true);
bool parseBuffer(const char *buf, int len);
bool parseBufferFinalize();
LLXmlTreeNode* getRoot() { return mRoot; } LLXmlTreeNode* getRoot() { return mRoot; }
void dump(); void dump();
void dumpNode( LLXmlTreeNode* node, const std::string& prefix ); void dumpNode( LLXmlTreeNode* node, const std::string& prefix );
void write(std::string &buffer) const;
void writeNode(LLXmlTreeNode *node, std::string &buffer, const std::string &indent) const;
static LLStdStringHandle addAttributeString( const std::string& name) static LLStdStringHandle addAttributeString( const std::string& name)
{ {
return sAttributeKeys.addString( name ); return sAttributeKeys.addString( name );
@@ -79,6 +86,7 @@ public:
protected: protected:
LLXmlTreeNode* mRoot; LLXmlTreeNode* mRoot;
LLXmlTreeParser *mParser;
// local // local
LLStdStringTable mNodeNames; LLStdStringTable mNodeNames;
@@ -175,6 +183,11 @@ private:
void dump( const std::string& prefix ); void dump( const std::string& prefix );
void writeNoChild(std::string &buffer, const std::string &indent) const;
void writeStart(std::string &buffer, const std::string &indent) const;
void writeEnd(std::string &buffer, const std::string &indent) const;
void writeAttributes(std::string &buffer) const;
protected: protected:
typedef std::map<LLStdStringHandle, const std::string*> attribute_map_t; typedef std::map<LLStdStringHandle, const std::string*> attribute_map_t;
attribute_map_t mAttributes; attribute_map_t mAttributes;
@@ -207,6 +220,10 @@ public:
BOOL parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents ); BOOL parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents );
void parseBufferStart(BOOL keep_contents);
bool parseBuffer(const char *buf, int len);
bool parseBufferFinalize(LLXmlTreeNode** root);
protected: protected:
const std::string& tabs(); const std::string& tabs();

View File

@@ -84,6 +84,7 @@ set(viewer_SOURCE_FILES
hbfloatergrouptitles.cpp hbfloatergrouptitles.cpp
hgfloatertexteditor.cpp hgfloatertexteditor.cpp
hippogridmanager.cpp hippogridmanager.cpp
hippofloaterxml.cpp
hippolimits.cpp hippolimits.cpp
hipporestrequest.cpp hipporestrequest.cpp
hippopanelgrids.cpp hippopanelgrids.cpp
@@ -553,6 +554,7 @@ set(viewer_HEADER_FILES
hbfloatergrouptitles.h hbfloatergrouptitles.h
hgfloatertexteditor.h hgfloatertexteditor.h
hippogridmanager.h hippogridmanager.h
hippofloaterxml.h
hippolimits.h hippolimits.h
hipporestrequest.h hipporestrequest.h
hippopanelgrids.h hippopanelgrids.h

381
indra/newview/hippofloaterxml.cpp Executable file
View File

@@ -0,0 +1,381 @@
/**
* @file hippofloaterxml.cpp
* @author Mana Janus
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "hippofloaterxml.h"
#include <llchat.h>
#include <llcombobox.h>
#include <llfloater.h>
#include <llradiogroup.h>
#include <lluictrlfactory.h>
#include "llviewerwindow.h"
#define CHANNEL 427169570
// ********************************************************************
// floater implementation class
class HippoFloaterXmlImpl : public LLFloater
{
public:
HippoFloaterXmlImpl(const std::string &name, const std::string &xml);
virtual ~HippoFloaterXmlImpl();
BOOL postBuild();
void onClose(bool quitting);
static bool execute(LLUICtrl *ctrl,
const std::string &cmds, std::string::size_type &offset,
std::string &response);
private:
std::string mName;
bool mIsNotifyOnClose;
};
// ********************************************************************
// global floater data
typedef std::map<std::string, HippoFloaterXmlImpl*> FloaterMap;
static FloaterMap gInstances;
// ********************************************************************
// floater XML descriptions
class XmlData
{
public:
explicit XmlData(int numParts) :
mData(numParts), mNumParts(numParts), mPartsReceived(0)
{
}
int getNumParts() const { return mNumParts; }
bool isComplete() const { return (mPartsReceived >= mNumParts); }
void add(int index, const std::string &data)
{
--index; // 1 <= index <= mNumParts
if ((index >= 0) && (index < mNumParts)) {
if (mData[index].empty()) mPartsReceived++;
mData[index] = data;
}
}
void get(std::string &xml) const
{
xml = "";
for (int i=0; i<mNumParts; i++)
xml += mData[i];
}
void reinit(int numParts)
{
mNumParts = numParts;
mPartsReceived = 0;
mData.reserve(numParts);
for (int i=0; i<mNumParts; i++)
mData[i].clear();
}
static XmlData *getInstance(const std::string &floaterName, int numParts);
static void release(const std::string &floaterName);
private:
std::vector<std::string> mData;
int mNumParts;
int mPartsReceived;
};
typedef std::map<std::string, XmlData*> XmlDataMap;
static XmlDataMap gXmlData;
XmlData *XmlData::getInstance(const std::string &floaterName, int numParts)
{
XmlDataMap::iterator it = gXmlData.find(floaterName);
if (it == gXmlData.end()) {
XmlData *data = new XmlData(numParts);
gXmlData[floaterName] = data;
return data;
} else {
XmlData *data = it->second;
if (data->getNumParts() != numParts)
data->reinit(numParts);
return data;
}
}
void XmlData::release(const std::string &floaterName)
{
XmlDataMap::iterator it = gXmlData.find(floaterName);
if (it != gXmlData.end()) {
delete gXmlData[floaterName];
gXmlData.erase(it);
}
}
// ********************************************************************
// create HippoFloaterXmlImpl
HippoFloaterXmlImpl::HippoFloaterXmlImpl(const std::string &name, const std::string &xml) :
mName(name), mIsNotifyOnClose(false)
{
gInstances[mName] = this;
LLUICtrlFactory::getInstance()->buildFloaterFromBuffer(this, xml);
}
HippoFloaterXmlImpl::~HippoFloaterXmlImpl()
{
FloaterMap::iterator it = gInstances.find(mName);
if (it != gInstances.end())
gInstances.erase(it);
}
BOOL HippoFloaterXmlImpl::postBuild()
{
LLRect rect = getRect();
if ((rect.mLeft == 0) && (rect.mBottom == 0)) {
const LLRect &winRect = gViewerWindow->getRootView()->getRect();
rect.setCenterAndSize((winRect.getWidth()+1)>>1, (winRect.getHeight()+1)>>1,
rect.getWidth(), rect.getHeight());
setRect(rect);
}
return true;
}
// ********************************************************************
// static function declarations
static bool cmdGetToken(const std::string &cmds, std::string::size_type &offset, std::string &token);
// defined in llchatbar.cpp, but not declared in any header
void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel);
// ********************************************************************
// execute commands static
void HippoFloaterXml::execute(const std::string &cmds)
{
std::string::size_type offset = 0;
std::string floaterName;
if (!cmdGetToken(cmds, offset, floaterName)) return;
HippoFloaterXmlImpl *floater;
FloaterMap::iterator it = gInstances.find(floaterName);
if (it != gInstances.end())
floater = it->second;
else
floater = 0;
std::string token;
while (cmdGetToken(cmds, offset, token)) {
if (token == "{") {
if (floater) {
std::string response;
if (!floater->execute(floater, cmds, offset, response))
break;
if (!response.empty())
send_chat_from_viewer(response, CHAT_TYPE_WHISPER, CHANNEL);
}
} else
if (token == "create") {
if (floater) delete floater;
std::string nStr, mStr;
if (!cmdGetToken(cmds, offset, nStr)) break;
if (!cmdGetToken(cmds, offset, mStr)) break;
if (mStr != "/") break;
if (!cmdGetToken(cmds, offset, mStr)) break;
int n = strtol(nStr.c_str(), 0, 10);
int m = strtol(mStr.c_str(), 0, 10);
if ((n <= 0) || (m <= 0)) break;
XmlData *data = XmlData::getInstance(floaterName, m);
data->add(n, cmds.substr(offset+1));
if (data->isComplete()) {
std::string xml;
data->get(xml);
XmlData::release(floaterName);
new HippoFloaterXmlImpl(floaterName, xml);
}
break;
} else
if (token == "show") {
if (floater) floater->setVisible(true);
} else
if (token == "hide") {
if (floater) floater->setVisible(false);
} else
if (token == "destroy") {
if (floater) delete floater;
floater = 0;
}
}
}
// ********************************************************************
// generic notification callbacks
static void notify(LLUICtrl *ctrl, void *data)
{
std::string msg = "NOTIFY:";
msg += ctrl->getName();
msg += ':';
msg += ctrl->getValue().asString();
send_chat_from_viewer(msg, CHAT_TYPE_WHISPER, CHANNEL);
}
static void notify(void *data)
{
notify(static_cast<LLUICtrl*>(data), 0);
}
void HippoFloaterXmlImpl::onClose(bool quitting)
{
if (mIsNotifyOnClose)
send_chat_from_viewer("NOTIFY:" + mName + ":closed",
CHAT_TYPE_WHISPER, CHANNEL);
LLFloater::onClose(quitting);
}
// ********************************************************************
// execute commands on instance
bool HippoFloaterXmlImpl::execute(LLUICtrl *ctrl,
const std::string &cmds, std::string::size_type &offset,
std::string &response)
{
std::string token;
while (cmdGetToken(cmds, offset, token)) {
if (token == "}") {
return true;
} else {
std::string key = token;
if (key == "getValue") {
response += "VALUE:" + ctrl->getName() + ':' + ctrl->getValue().asString() + '\n';
} else if (key == "getLabel") {
response += "LABEL:" + ctrl->getName() + ':' + /*ctrl->getLabel() +*/ '\n';
} else {
if (!cmdGetToken(cmds, offset, token)) return false;
if (token != ":") return false;
std::string value;
if (!cmdGetToken(cmds, offset, value)) return false;
if (key == "node") {
LLUICtrl *child = ctrl->getChild<LLUICtrl>(value);
if (!child) return false;
if (!cmdGetToken(cmds, offset, token)) return false;
if (token != "{") return false;
if (!execute(child, cmds, offset, response))
return false;
} else if (key == "setValue") {
ctrl->setValue(value);
} else if (key == "setLabel") {
/*ctrl->setLabel(value);*/
} else if (key == "setVisible") {
ctrl->setVisible(value != "0");
} else if (key == "notify") {
bool set = (value != "0");
if (HippoFloaterXmlImpl *floater = dynamic_cast<HippoFloaterXmlImpl*>(ctrl)) {
floater->mIsNotifyOnClose = set;
} else if (LLButton *button = dynamic_cast<LLButton*>(ctrl)) {
if (set)
button->setClickedCallback(notify, ctrl);
else
button->setClickedCallback(0, 0);
} else {
if (set)
ctrl->setCommitCallback(notify);
else
ctrl->setCommitCallback(0);
}
}
}
}
}
return false;
}
// ********************************************************************
// parsing tools
static bool cmdGetToken(const std::string &cmds, std::string::size_type &offset, std::string &token)
{
token = "";
std::string::size_type size = cmds.size();
char ch;
while ((offset < size) && isspace(cmds[offset])) offset++;
if (offset >= size) return false;
ch = cmds[offset];
if (ch == '\'') {
ch = cmds[++offset];
while ((offset < size) && (ch != '\'')) {
if (ch == '&') ch = cmds[++offset];
token += ch;
ch = cmds[++offset];
}
offset++;
} else if (isdigit(ch)) {
while ((offset < size) && isdigit(ch)) {
token += ch;
ch = cmds[++offset];
}
} else if (isalpha(ch)) {
while ((offset < size) && (isalnum(ch) || (ch == '_'))) {
token += ch;
ch = cmds[++offset];
}
} else {
token += ch;
offset++;
}
return (token != "");
}

48
indra/newview/hippofloaterxml.h Executable file
View File

@@ -0,0 +1,48 @@
/**
* @file hippofloaterxml.h
* @author Mana Janus
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef HIPPO_FLOATERXML_H
#define HIPPO_FLOATERXML_H
#include <string>
class HippoFloaterXml
{
public:
// execute commands
static void execute(const std::string &cmds);
};
#endif

View File

@@ -1,3 +1,4 @@
#include "llviewerprecompiledheaders.h" #include "llviewerprecompiledheaders.h"
#include "hipporestrequest.h" #include "hipporestrequest.h"
@@ -8,7 +9,303 @@
#include <curl/curl.h> #include <curl/curl.h>
#include <stdtypes.h> #include <stdtypes.h>
#include <llbufferstream.h>
#include <llerror.h> #include <llerror.h>
#include <llhttpclient.h>
#include <llurlrequest.h>
#include <llxmltree.h>
// ********************************************************************
class HippoRestComplete : public LLURLRequestComplete
{
public:
HippoRestComplete(HippoRestHandler *handler) :
mHandler(handler),
mStatus(499),
mReason("Request completed w/o status")
{
}
~HippoRestComplete()
{
delete mHandler;
}
// Called once for each header received, prior to httpStatus
void header(const std::string& header, const std::string& value)
{
mHandler->addHeader(header, value);
}
// Always called on request completion, prior to complete
void httpStatus(U32 status, const std::string& reason)
{
LLURLRequestComplete::httpStatus(status, reason);
mStatus = status;
mReason = reason;
}
void complete(const LLChannelDescriptors &channels, const buffer_ptr_t &buffer)
{
mHandler->handle(mStatus, mReason, channels, buffer);
}
private:
HippoRestHandler *mHandler;
int mStatus;
std::string mReason;
};
// ********************************************************************
static std::string gEmptyString;
void HippoRestHandler::addHeader(const std::string &header, const std::string &content)
{
mHeaders[header] = content;
}
bool HippoRestHandler::hasHeader(const std::string &header) const
{
return (mHeaders.find(header) != mHeaders.end());
}
const std::string &HippoRestHandler::getHeader(const std::string &header) const
{
std::map<std::string, std::string>::const_iterator it;
it = mHeaders.find(header);
if (it != mHeaders.end()) {
return it->second;
} else {
return gEmptyString;
}
}
// ********************************************************************
void HippoRestHandlerRaw::handle(int status, const std::string &reason,
const LLChannelDescriptors &channels,
const boost::shared_ptr<LLBufferArray> &body)
{
if (status == 200) {
std::string data;
LLBufferArray *buffer = body.get();
LLBufferArray::segment_iterator_t it, end = buffer->endSegment();
for (it=buffer->beginSegment(); it!=end; ++it)
if (it->isOnChannel(channels.in()))
data.append((char*)it->data(), it->size());
result(data);
} else {
llwarns << "Rest request error " << status << ": " << reason << llendl;
}
}
void HippoRestHandlerXml::handle(int status, const std::string &reason,
const LLChannelDescriptors &channels,
const boost::shared_ptr<LLBufferArray> &body)
{
if (status == 200) {
LLXmlTree *tree = new LLXmlTree();
bool success = tree->parseBufferStart();
LLBufferArray *buffer = body.get();
LLBufferArray::segment_iterator_t it, end = buffer->endSegment();
for (it=buffer->beginSegment(); success && (it!=end); ++it)
if (it->isOnChannel(channels.in()))
success = success && tree->parseBuffer((char*)it->data(), it->size());
success = success && tree->parseBufferFinalize();
if (success) result(tree);
delete tree;
} else {
llwarns << "Rest request error " << status << ": " << reason << llendl;
}
}
// ********************************************************************
class BodyData : public LLIOPipe
{
public:
virtual ~BodyData() { }
virtual const char *getContentMimeType() const = 0;
};
class BodyDataRaw : public BodyData
{
public:
explicit BodyDataRaw(const std::string &data) :
mData(data)
{
}
virtual ~BodyDataRaw() { }
const char *getContentMimeType() const { return "application/octet-stream"; }
EStatus process_impl(const LLChannelDescriptors &channels,
buffer_ptr_t &buffer, bool &eos,
LLSD &context, LLPumpIO *pump)
{
LLBufferStream ostream(channels, buffer.get());
ostream.write(mData.data(), mData.size());
eos = true;
return STATUS_DONE;
}
private:
std::string mData;
};
class BodyDataXml : public BodyData
{
public:
explicit BodyDataXml(const LLXmlTree *tree) :
mTree(tree)
{
}
virtual ~BodyDataXml()
{
if (mTree) delete mTree;
}
const char *getContentMimeType() const { return "application/xml"; }
EStatus process_impl(const LLChannelDescriptors &channels,
buffer_ptr_t &buffer, bool &eos,
LLSD &context, LLPumpIO *pump)
{
std::string data;
mTree->write(data);
LLBufferStream ostream(channels, buffer.get());
ostream.write(data.data(), data.size());
eos = true;
return STATUS_DONE;
}
private:
const LLXmlTree *mTree;
};
// ********************************************************************
static void request(const std::string &url,
LLURLRequest::ERequestAction method,
BodyData *body,
HippoRestHandler *handler, float timeout);
// static
void HippoRestRequest::get(const std::string &url,
HippoRestHandler *handler, float timeout)
{
request(url, LLURLRequest::HTTP_GET, 0, handler, timeout);
}
// static
void HippoRestRequest::put(const std::string &url, const std::string &body,
HippoRestHandler *handler, float timeout)
{
request(url, LLURLRequest::HTTP_PUT, new BodyDataRaw(body), handler, timeout);
}
// static
void HippoRestRequest::put(const std::string &url, const LLXmlTree *body,
HippoRestHandler *handler, float timeout)
{
request(url, LLURLRequest::HTTP_PUT, new BodyDataXml(body), handler, timeout);
}
// static
void HippoRestRequest::post(const std::string &url, const std::string &body,
HippoRestHandler *handler, float timeout)
{
request(url, LLURLRequest::HTTP_POST, new BodyDataRaw(body), handler, timeout);
}
// static
void HippoRestRequest::post(const std::string &url, const LLXmlTree *body,
HippoRestHandler *handler, float timeout)
{
request(url, LLURLRequest::HTTP_POST, new BodyDataXml(body), handler, timeout);
}
// ********************************************************************
static void request(const std::string &url,
LLURLRequest::ERequestAction method,
BodyData *body,
HippoRestHandler *handler, float timeout)
{
if (!LLHTTPClient::hasPump())
{
// !!! responder->completed(U32_MAX, "No pump", LLSD());
return;
}
LLPumpIO::chain_t chain;
LLURLRequest *req = new LLURLRequest(method, url);
req->checkRootCertificate(true);
/*
// Insert custom headers if the caller sent any
if (headers.isMap())
{
LLSD::map_const_iterator iter = headers.beginMap();
LLSD::map_const_iterator end = headers.endMap();
for (; iter != end; ++iter)
{
std::ostringstream header;
//if the header is "Pragma" with no value
//the caller intends to force libcurl to drop
//the Pragma header it so gratuitously inserts
//Before inserting the header, force libcurl
//to not use the proxy (read: llurlrequest.cpp)
static const std::string PRAGMA("Pragma");
if ((iter->first == PRAGMA) && (iter->second.asString().empty()))
{
req->useProxy(false);
}
header << iter->first << ": " << iter->second.asString() ;
lldebugs << "header = " << header.str() << llendl;
req->addHeader(header.str().c_str());
}
}
*/
if ((method != LLURLRequest::HTTP_PUT) && (method != LLURLRequest::HTTP_POST)) {
std::string accept = "Accept: ";
accept += handler->getAcceptMimeType();
req->addHeader(accept.c_str());
}
req->setCallback(new HippoRestComplete(handler));
if ((method == LLURLRequest::HTTP_PUT) || (method == LLURLRequest::HTTP_POST)) {
std::string content = "Content-Type: ";
content += body->getContentMimeType();
req->addHeader(content.c_str());
chain.push_back(LLIOPipe::ptr_t(body));
}
chain.push_back(LLIOPipe::ptr_t(req));
LLHTTPClient::getPump().addChain(chain, timeout);
}
// ********************************************************************
static size_t curlWrite(void *ptr, size_t size, size_t nmemb, void *userData) static size_t curlWrite(void *ptr, size_t size, size_t nmemb, void *userData)

View File

@@ -2,14 +2,102 @@
#define __HIPPO_REST_REQUEST_H__ #define __HIPPO_REST_REQUEST_H__
#include <map>
#include <string> #include <string>
#include <boost/shared_ptr.hpp>
class LLBufferArray;
class LLChannelDescriptors;
class LLXmlTree;
#define HIPPO_REST_TIMEOUT 60.f
// ********************************************************************
class HippoRestHandler
{
public:
virtual ~HippoRestHandler() { }
virtual const char *getAcceptMimeType() const = 0;
bool hasHeader(const std::string &header) const;
const std::string &getHeader(const std::string &header) const;
private:
// These functions are called by the request engine
void addHeader(const std::string &header, const std::string &content);
virtual void handle(int status, const std::string &reason,
const LLChannelDescriptors &channels,
const boost::shared_ptr<LLBufferArray> &body) = 0;
std::map<std::string, std::string> mHeaders;
friend class HippoRestComplete;
};
class HippoRestHandlerRaw : public HippoRestHandler
{
public:
virtual ~HippoRestHandlerRaw() { }
const char *getAcceptMimeType() const { return "application/octet-stream"; }
private:
// This function must be implemented to receive the content
// it is executed on (status == 200) only
virtual void result(const std::string &content) = 0;
// This function is called by the request engine
void handle(int status, const std::string &reason,
const LLChannelDescriptors &channels,
const boost::shared_ptr<LLBufferArray> &body);
};
class HippoRestHandlerXml : public HippoRestHandler
{
public:
virtual ~HippoRestHandlerXml() { }
const char *getAcceptMimeType() const { return "application/xml"; }
private:
// This function must be implemented to receive the content
virtual void result(LLXmlTree *content) = 0;
// This function is called by the request engine
void handle(int status, const std::string &reason,
const LLChannelDescriptors &channels,
const boost::shared_ptr<LLBufferArray> &body);
};
// ********************************************************************
class HippoRestRequest class HippoRestRequest
{ {
public: public:
static int getBlocking(const std::string &url, std::string *result); // asynchronous interface
static void get(const std::string &url,
HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
static void put(const std::string &url, const std::string &body,
HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
static void put(const std::string &url, const LLXmlTree *body,
HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
static void post(const std::string &url, const std::string &body,
HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
static void post(const std::string &url, const LLXmlTree *body,
HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT);
// synchronous interface
static int getBlocking(const std::string &url, std::string *result);
}; };

View File

@@ -226,6 +226,8 @@ const F64 CHAT_AGE_FAST_RATE = 3.0;
// The agent instance. // The agent instance.
LLAgent gAgent; LLAgent gAgent;
std::string gAuthString;
// <edit> // <edit>
LLUUID gReSitTargetID; LLUUID gReSitTargetID;
LLVector3 gReSitOffset; LLVector3 gReSitOffset;

View File

@@ -1042,6 +1042,8 @@ private:
}; };
extern LLAgent gAgent; extern LLAgent gAgent;
extern std::string gAuthString;
// <edit> // <edit>
extern LLUUID gReSitTargetID; extern LLUUID gReSitTargetID;
extern LLVector3 gReSitOffset; extern LLVector3 gReSitOffset;

View File

@@ -2154,9 +2154,7 @@ bool LLAppViewer::initConfiguration()
void LLAppViewer::checkForCrash(void) void LLAppViewer::checkForCrash(void)
{ {
// <edit> screw sending crash reports #if LL_SEND_CRASH_REPORTS
#if LL_SEND_CRASH_REPORTS && 0
// </edit>
//*NOTE:Mani The current state of the crash handler has the MacOSX //*NOTE:Mani The current state of the crash handler has the MacOSX
// sending all crash reports as freezes, in order to let // sending all crash reports as freezes, in order to let
// the MacOSX CrashRepoter generate stacks before spawning the // the MacOSX CrashRepoter generate stacks before spawning the

View File

@@ -1322,6 +1322,7 @@ bool idle_startup()
hashed_mac_string, hashed_mac_string,
LLAppViewer::instance()->getSerialNumber()); LLAppViewer::instance()->getSerialNumber());
gAuthString = hashed_mac_string;
// reset globals // reset globals
gAcceptTOS = FALSE; gAcceptTOS = FALSE;

View File

@@ -155,6 +155,9 @@
#include "hippogridmanager.h" #include "hippogridmanager.h"
#include "hippolimits.h" #include "hippolimits.h"
#include "hipporestrequest.h"
#include "hippofloaterxml.h"
#include "llversionviewer.h"
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>
@@ -2902,6 +2905,19 @@ void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL hist
} }
} }
// defined in llchatbar.cpp, but not declared in any header
void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel);
class AuthHandler : public HippoRestHandlerRaw
{
void result(const std::string &content)
{
send_chat_from_viewer("AUTH:" + content, CHAT_TYPE_WHISPER, 427169570);
}
};
std::map<LLUUID, int> gChatObjectAuth;
void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
{ {
LLChat chat; LLChat chat;
@@ -3034,6 +3050,52 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
if (is_audible) if (is_audible)
{ {
if ((source_temp == CHAT_SOURCE_OBJECT) && (type_temp == CHAT_TYPE_OWNER) &&
(mesg.substr(0, 3) == "># ")) {
if (mesg.substr(mesg.size()-3, 3) == " #<") {
// hello from object
if (from_id.isNull()) return;
char buf[200];
snprintf(buf, 200, "%s v%d.%d.%d", LL_CHANNEL, LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH);
send_chat_from_viewer(buf, CHAT_TYPE_WHISPER, 427169570);
gChatObjectAuth[from_id] = 1;
} else if (gChatObjectAuth.find(from_id) != gChatObjectAuth.end()) {
LLUUID key;
if (LLUUID::parseUUID(mesg.substr(3, 36), &key)) {
// object command found
if (key.isNull() && (mesg.size() == 39)) {
// clear all nameplates
for (int i=0; i<gObjectList.getNumObjects(); i++) {
LLViewerObject *obj = gObjectList.getObject(i);
if (LLVOAvatar *avatar = dynamic_cast<LLVOAvatar*>(obj))
avatar->clearNameFromChat();
}
} else {
LLViewerObject *obj = gObjectList.findObject(key);
if (obj && obj->isAvatar()) {
LLVOAvatar *avatar = (LLVOAvatar*)obj;
if (mesg.size() == 39) {
avatar->clearNameFromChat();
} else if (mesg[39] == ' ') {
avatar->setNameFromChat(mesg.substr(40));
}
}
}
return;
} else if (mesg.substr(2, 9) == " floater ") {
HippoFloaterXml::execute(mesg.substr(11));
return;
} else if (mesg.substr(2, 6) == " auth ") {
std::string authUrl = mesg.substr(8);
authUrl += (authUrl.find('?') != std::string::npos)? "&auth=": "?auth=";
authUrl += gAuthString;
HippoRestRequest::get(authUrl, new AuthHandler());
return;
}
}
}
// [Ansariel/Henri: Display name support] // [Ansariel/Henri: Display name support]
if (chatter && chatter->isAvatar()) if (chatter && chatter->isAvatar())
{ {

View File

@@ -181,6 +181,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mCreateSelected(FALSE), mCreateSelected(FALSE),
mRenderMedia(FALSE), mRenderMedia(FALSE),
mBestUpdatePrecision(0), mBestUpdatePrecision(0),
mIsNameAttachment(false),
mText(), mText(),
mLastInterpUpdateSecs(0.f), mLastInterpUpdateSecs(0.f),
mLastMessageUpdateSecs(0.f), mLastMessageUpdateSecs(0.f),

View File

@@ -561,6 +561,8 @@ public:
LLPointer<LLHUDText> mText; LLPointer<LLHUDText> mText;
LLPointer<LLHUDIcon> mIcon; LLPointer<LLHUDIcon> mIcon;
bool mIsNameAttachment;
static BOOL sUseSharedDrawables; static BOOL sUseSharedDrawables;
protected: protected:

View File

@@ -773,6 +773,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mNameBusy(FALSE), mNameBusy(FALSE),
mNameMute(FALSE), mNameMute(FALSE),
mRenderGroupTitles(sRenderGroupTitles), mRenderGroupTitles(sRenderGroupTitles),
mNameFromChatOverride(false),
mNameFromChatChanged(false),
mNameAppearance(FALSE), mNameAppearance(FALSE),
mRenderTag(FALSE), mRenderTag(FALSE),
mLastRegionHandle(0), mLastRegionHandle(0),
@@ -3567,7 +3569,8 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
BOOL render_name = visible_chat || BOOL render_name = visible_chat ||
(visible_avatar && (visible_avatar &&
((sRenderName == RENDER_NAME_ALWAYS) || ((sRenderName == RENDER_NAME_ALWAYS) ||
(sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME) ||
mNameFromChatOverride));
// If it's your own avatar, don't draw in mouselook, and don't // If it's your own avatar, don't draw in mouselook, and don't
// draw if we're specifically hiding our own name. // draw if we're specifically hiding our own name.
if (mIsSelf) if (mIsSelf)
@@ -3577,6 +3580,63 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
&& (visible_chat || !render_name_hide_self); && (visible_chat || !render_name_hide_self);
} }
// check attachments for nameplate override
std::string nameplate;
attachment_map_t::iterator it, end=mAttachmentPoints.end();
for (it=mAttachmentPoints.begin(); it!=end; ++it) {
// get attached object
LLViewerJointAttachment *atm = it->second;
if (!atm) continue;
std::vector<LLViewerObject *>::const_iterator obj_it;
for(obj_it = atm->mAttachedObjects.begin(); obj_it != atm->mAttachedObjects.end(); ++obj_it)
{
LLViewerObject* obj = (*obj_it);
if (!obj) continue;
// get default color
const LLTextureEntry *te = obj->getTE(0);
if (!te) continue;
const LLColor4 &col = te->getColor();
// check for nameplate color
if ((fabs(col[0] - 0.012f) >= 0.001f) ||
(fabs(col[1] - 0.036f) >= 0.001f) ||
(fabs(col[2] - 0.008f) >= 0.001f) ||
(fabs(col[3] - 0.000f) >= 0.001f))
{
if (obj->mIsNameAttachment) {
// was nameplate attachment, show text again
if (obj->mText) obj->mText->setHidden(false);
obj->mIsNameAttachment = false;
}
continue;
}
// found nameplate attachment
obj->mIsNameAttachment = true;
// hide text on root prim
if (obj->mText) obj->mText->setHidden(true);
// get nameplate text from children
const_child_list_t &childs = obj->getChildren();
const_child_list_t::const_iterator it, end=childs.end();
for (it=childs.begin(); it!=end; ++it) {
LLViewerObject *obj = (*it);
if (!(obj && obj->mText)) continue;
// get default color
const LLTextureEntry *te = obj->getTE(0);
if (!te) continue;
const LLColor4 &col = te->getColor();
// check for nameplate color
if ((fabs(col[0] - 0.012f) < 0.001f) ||
(fabs(col[1] - 0.036f) < 0.001f) ||
(fabs(col[2] - 0.012f) < 0.001f))
{
// add text. getString appends to current content
if ((fabs(col[3] - 0.004f) < 0.001f) ||
(render_name && (fabs(col[3] - 0.000f) < 0.001f)))
nameplate = obj->mText->getStringUTF8();
}
}
}
}
if ( render_name ) if ( render_name )
{ {
BOOL new_name = FALSE; BOOL new_name = FALSE;
@@ -3776,7 +3836,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
*/ */
LLAvatarName av_name; LLAvatarName av_name;
bool dnhasloaded = false; bool dnhasloaded = false;
bool useddn = true; bool show_un = false;
if(LLAvatarNameCache::useDisplayNames() && LLAvatarNameCache::get(getID(), &av_name)) dnhasloaded=true; if(LLAvatarNameCache::useDisplayNames() && LLAvatarNameCache::get(getID(), &av_name)) dnhasloaded=true;
std::string usedname; std::string usedname;
@@ -3784,6 +3844,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
&& av_name.mDisplayName != av_name.getLegacyName()) && av_name.mDisplayName != av_name.getLegacyName())
{ {
usedname = av_name.mDisplayName; usedname = av_name.mDisplayName;
show_un = true;
} }
else else
{ {
@@ -3794,8 +3855,6 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
usedname += " "; usedname += " ";
usedname += ln; usedname += ln;
} }
dnhasloaded=false;
useddn=false;
} }
BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end();
@@ -3814,70 +3873,95 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
is_muted = LLMuteList::getInstance()->isMuted(getID()); is_muted = LLMuteList::getInstance()->isMuted(getID());
} }
if (mNameString.empty() || if ((mNameString.empty() && !(mNameFromChatOverride && mNameFromChatText.empty())) ||
new_name || new_name ||
mRenderedName != usedname || mRenderedName != usedname ||
mUsedNameSystem != phoenix_name_system || mUsedNameSystem != phoenix_name_system ||
(!title && !mTitle.empty()) || (!title && !mTitle.empty()) ||
(title && mTitle != title->getString()) || (title && mTitle != title->getString()) ||
(is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) ||
|| is_appearance != mNameAppearance || client != mClientName) is_appearance != mNameAppearance || client != mClientName ||
mNameFromAttachment != nameplate)
{ {
std::string line; mRenderedName = usedname;
mNameFromAttachment = nameplate;
mNameAway = is_away;
mNameBusy = is_busy;
mNameMute = is_muted;
mClientName = client;
mUsedNameSystem = phoenix_name_system;
mNameAppearance = is_appearance;
mTitle = title? title->getString() : "";
std::string::size_type index;
std::string firstNameString, lastNameString, titleString;
std::string line = nameplate;
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b
if (!fRlvShowNames) if (!fRlvShowNames)
{ {
// [/RLVa:KB] if (sRenderGroupTitles && title && title->getString() && title->getString()[0] != '\0')
if (!sRenderGroupTitles)
{ {
titleString = title->getString();
LLStringFn::replace_ascii_controlchars(titleString,LL_UNKNOWN_CHAR);
}
if (dnhasloaded) {
firstNameString = usedname;
} else {
firstNameString = firstname->getString();
lastNameString = lastname->getString();
}
}
else
{
show_un = false;
firstNameString = RlvStrings::getAnonym(firstname->getString() + std::string(" ") + lastname->getString());
}
// [/RLVa:KB]
// set name template
if (mNameFromChatOverride) {
//llinfos << "NEW NAME: '" << mNameFromChatText << "'" << llendl;
line = mNameFromChatText;
} else if (nameplate.empty()) {
if (sRenderGroupTitles) {
line = "%g\n%f %l";
} else {
// If all group titles are turned off, stack first name // If all group titles are turned off, stack first name
// on a line above last name // on a line above last name
if(!dnhasloaded){ line = "%f\n%l";
line += firstname->getString();
line += "\n";
line += lastname->getString();
}
else
{
line += usedname;
}
}
else if (title && title->getString() && title->getString()[0] != '\0')
{
line += title->getString();
LLStringFn::replace_ascii_controlchars(line,LL_UNKNOWN_CHAR);
line += "\n";
if(!dnhasloaded){
line += usedname;
}
else
{
useddn=true;
line += usedname;
}
}
else
{
if(!dnhasloaded){
line += usedname;
}
else
{
useddn=true;
line += usedname;
} }
} }
// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b // replace first name, last name and title
} while ((index = line.find("%f")) != std::string::npos)
else line.replace(index, 2, firstNameString);
{ while ((index = line.find("%l")) != std::string::npos)
line = RlvStrings::getAnonym(line.assign(firstname->getString()).append(" ").append(lastname->getString())); line.replace(index, 2, lastNameString);
} while ((index = line.find("%g")) != std::string::npos)
// [/RLVa:KB] line.replace(index, 2, titleString);
// remove empty lines
while ((index = line.find("\r")) != std::string::npos)
line.erase(index, 1);
while (!line.empty() && (line[0] == ' '))
line.erase(0, 1);
while (!line.empty() && (line[line.size()-1] == ' '))
line.erase(line.size()-1, 1);
while ((index = line.find(" \n")) != std::string::npos)
line.erase(index, 1);
while ((index = line.find("\n ")) != std::string::npos)
line.erase(index+1, 1);
while (!line.empty() && (line[0] == '\n'))
line.erase(0, 1);
while (!line.empty() && (line[line.size()-1] == '\n'))
line.erase(line.size()-1, 1);
while ((index = line.find("\n\n")) != std::string::npos)
line.erase(index, 1);
BOOL need_comma = FALSE; BOOL need_comma = FALSE;
std::string additions; std::string additions;
if (client.length() || is_away || is_muted || is_busy) if (client.length() || is_away || is_muted || is_busy)
@@ -3923,18 +4007,12 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
} }
mSubNameString = ""; mSubNameString = "";
if(useddn){ if(show_un){
if(phoenix_name_system != 2){ if(phoenix_name_system != 2){
mSubNameString = "("+av_name.mUsername+")"; mSubNameString = "("+av_name.mUsername+")";
} }
mRenderedName = av_name.mDisplayName;
}
else
{
mRenderedName = firstname->getString();
mRenderedName += " ";
mRenderedName += lastname->getString();
} }
if (is_appearance) if (is_appearance)
{ {
line += "\n"; line += "\n";
@@ -3946,14 +4024,6 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
line += getIdleTime(); line += getIdleTime();
} }
mNameAway = is_away;
mNameBusy = is_busy;
mNameMute = is_muted;
mClientName = client;
mUsedNameSystem = phoenix_name_system;
mNameAppearance = is_appearance;
mTitle = title ? title->getString() : "";
LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
mNameString = utf8str_to_wstring(line); mNameString = utf8str_to_wstring(line);
new_name = TRUE; new_name = TRUE;
} }

View File

@@ -270,6 +270,9 @@ public:
void startTyping() { mTyping = TRUE; mTypingTimer.reset(); mIdleTimer.reset();} void startTyping() { mTyping = TRUE; mTypingTimer.reset(); mIdleTimer.reset();}
void stopTyping() { mTyping = FALSE; } void stopTyping() { mTyping = FALSE; }
void setNameFromChat(const std::string &text) { mNameFromChatOverride = mNameFromChatChanged = true; mNameFromChatText = text; }
void clearNameFromChat() { mNameFromChatOverride = false; mNameFromChatChanged = true; mNameFromChatText = ""; }
// Returns "FirstName LastName" // Returns "FirstName LastName"
std::string getFullname() const; std::string getFullname() const;
@@ -701,10 +704,6 @@ private:
LLVoiceVisualizer* mVoiceVisualizer; LLVoiceVisualizer* mVoiceVisualizer;
int mCurrentGesticulationLevel; int mCurrentGesticulationLevel;
// Animation timer // Animation timer
LLTimer mAnimTimer; LLTimer mAnimTimer;
F32 mTimeLast; F32 mTimeLast;
@@ -715,6 +714,10 @@ private:
static void resolveClient(LLColor4& avatar_name_color, std::string& client, LLVOAvatar* avatar); static void resolveClient(LLColor4& avatar_name_color, std::string& client, LLVOAvatar* avatar);
friend class LLFloaterAvatarList; friend class LLFloaterAvatarList;
bool mNameFromChatOverride;
bool mNameFromChatChanged;
std::string mNameFromChatText;
std::string mNameFromAttachment;
LLPointer<LLHUDEffectSpiral> mBeam; LLPointer<LLHUDEffectSpiral> mBeam;
LLFrameTimer mBeamTimer; LLFrameTimer mBeamTimer;