Compare commits

..

31 Commits

Author SHA1 Message Date
Shyotl
8a16e6c99f Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-08 18:18:19 -05:00
Shyotl
f36e8fbeca Better crashdump context. 2020-04-08 18:11:09 -05:00
Liru Færs
718ef09adf Fix removing/exporting picks when unable to add more
Wooops, wrote that wrong, must've been tired or something
2020-04-08 09:21:21 -04:00
Liru Færs
6443849ea9 Do not lookup strings in the toolbar per frame, ack! 2020-04-08 08:33:41 -04:00
Liru Færs
cbb7e473ba Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2020-04-08 06:59:48 -04:00
Liru Færs
118957362f Fix mismatched tag 2020-04-08 05:11:11 -04:00
Shyotl
ed7f73769f Potentially fix crash in LLSurface 2020-04-07 23:30:12 -05:00
Liru Færs
ae15dcb318 Merge 41224c57317b6c1b44528aa1dc1f13732cdffe6d from viewer-lion... sorta
Fixes broken default perms message sometimes popping up for certain avs
2020-04-07 16:55:58 -04:00
Liru Færs
c4af22481c Update mesh export code, cause why not. 2020-04-07 15:30:13 -04:00
Liru Færs
ae17f76bb4 Remove now unused LLIMInfo 2020-04-07 10:49:48 -04:00
Liru Færs
7e62d17fda Don't try to use region if it's null for permissions defaults 2020-04-07 05:56:06 -04:00
Liru Færs
f9185e8bc8 Fix mutelist popping up, I think
LLMuteList::add should return false if nothing new was added
2020-04-07 05:55:24 -04:00
Liru Færs
1361f9b57d Simplify selection of mute 2020-04-07 04:29:45 -04:00
Liru Færs
b86eae026b Sync to fix using gMessageSystem when it may not have the right message 2020-04-07 04:29:20 -04:00
Liru Færs
79d938a4f4 Sync LLMuteList code with upstream 2020-04-07 02:51:08 -04:00
Liru Færs
23068a70a2 Select Mute when muting object via Object profile 2020-04-06 07:53:42 -04:00
Shyotl
0aa5e0bb88 Close 'default permissions' window on client disconnect. Nonfunctional after that point anyhow. Also applying setting crashes due to null region after dc. 2020-04-05 14:56:35 -05:00
Router Gray
5040275969 [CMake] Releases shouldn't speak Greek. 2020-04-04 06:47:39 -05:00
Liru Færs
1daccf40ee Move the FMOD Powered By text, for Torric and others 2020-04-04 07:28:19 -04:00
Shyotl
4fd302286b Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-03 06:02:48 -05:00
Shyotl
18f9f19e61 Textures mid-decode potentially processing of other textures until complete. Disabled UDP texture fetch fallback when connected to official grid. 2020-04-03 06:01:58 -05:00
Liru Færs
1de6d4461a Add missing EmergencyTeleportSeconds preference to System->Security
Thanks for the heads up about this missing preferences, and for the
Spanish translation, Damian!
2020-04-03 02:53:41 -04:00
Shyotl
4198f47ab6 Fix header breakage in debug/relwithdebug 2020-04-03 00:33:19 -05:00
Shyotl
d9049ba342 Handle AISAPI throttling and status 410 a bit better. 2020-04-02 21:47:07 -05:00
Shyotl
f75ac3e4c2 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-02 20:09:53 -05:00
Liru Færs
06698deaca A couple more sim->region changes 2020-04-02 21:08:23 -04:00
Shyotl
445eb29bd3 Bring aisapi handling closer to LL (code 499 retry, match timeout values, etc) 2020-04-02 20:07:55 -05:00
Shyotl
cc034f6841 Fix inventory scrolling issue when navigating via keyboard. 2020-04-02 20:03:08 -05:00
Liru Færs
3c368651f1 Update crashpad, thanks Rye! 2020-04-02 20:39:01 -04:00
Damian Zhaoying
321730e384 More translations fixes in Area search and menu list owners. 2020-04-02 03:02:23 -03:00
Damian Zhaoying
c2fd88670f Fix some remaining spanish translations. 2020-04-02 02:36:20 -03:00
39 changed files with 590 additions and 778 deletions

View File

@@ -410,11 +410,11 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>4614b29cc98021cf1770a8290171602b</string> <string>a96fda7ad5cee967823f5c94390ba35b</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows/crashpad-ce32d093.7-windows-7.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows/crashpad-c6d76a90.194-windows-194.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows</string> <string>windows</string>
@@ -424,18 +424,18 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>d801461b7a6a40fffab828aa1e01e3e6</string> <string>5ff95ca1007ed2dc300b59de17453201</string>
<key>hash_algorithm</key> <key>hash_algorithm</key>
<string>md5</string> <string>md5</string>
<key>url</key> <key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows64/crashpad-ce32d093.7-windows64-7.tar.bz2</string> <string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows64/crashpad-c6d76a90.194-windows64-194.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows64</string> <string>windows64</string>
</map> </map>
</map> </map>
<key>version</key> <key>version</key>
<string>ce32d093.7</string> <string>c6d76a90.194</string>
</map> </map>
<key>curl</key> <key>curl</key>
<map> <map>

View File

@@ -270,6 +270,8 @@ if (NOT VIEWER_CHANNEL_GRK)
set(VIEWER_CHANNEL_GRK "\\u03B1") # "α" set(VIEWER_CHANNEL_GRK "\\u03B1") # "α"
elseif (VIEWER_CHANNEL_TYPE MATCHES "Beta") elseif (VIEWER_CHANNEL_TYPE MATCHES "Beta")
set(VIEWER_CHANNEL_GRK "\\u03B2") # "β" set(VIEWER_CHANNEL_GRK "\\u03B2") # "β"
else()
set(VIEWER_CHANNEL_GRK "")
endif () endif ()
endif (NOT VIEWER_CHANNEL_GRK) endif (NOT VIEWER_CHANNEL_GRK)

View File

@@ -353,10 +353,10 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// NEW Macros for debugging, allow the passing of a string tag // NEW Macros for debugging, allow the passing of a string tag
#if SHOW_DEBUG #ifdef SHOW_DEBUG
#define DO_DEBUG_LOG if(true) #define DO_DEBUG_LOG
#else #else
#define DO_DEBUG_LOG if(false) #define DO_DEBUG_LOG if (false)
#endif #endif
// Pass comma separated list of tags (currently only supports up to 0, 1, or 2) // Pass comma separated list of tags (currently only supports up to 0, 1, or 2)

View File

@@ -961,3 +961,4 @@ P(wholeModelFeeResponder);
P(wholeModelUploadResponder); P(wholeModelUploadResponder);
P2(XMLRPCResponder, connect_40s); P2(XMLRPCResponder, connect_40s);
P(getUpdateInfoResponder); P(getUpdateInfoResponder);
P2(AISAPIResponder, connect_60s);

View File

@@ -58,103 +58,6 @@ const std::string SYSTEM_FROM("Second Life");
const std::string INTERACTIVE_SYSTEM_FROM("F387446C-37C4-45f2-A438-D99CBDBB563B"); const std::string INTERACTIVE_SYSTEM_FROM("F387446C-37C4-45f2-A438-D99CBDBB563B");
const S32 IM_TTL = 1; const S32 IM_TTL = 1;
/**
* LLIMInfo
*/
LLIMInfo::LLIMInfo() :
mFromGroup(FALSE),
mParentEstateID(0),
mOffline(0),
mViewerThinksToIsOnline(false),
mIMType(IM_NOTHING_SPECIAL),
mTimeStamp(0),
mSource(IM_FROM_SIM),
mTTL(IM_TTL)
{
}
LLIMInfo::LLIMInfo(
const LLUUID& from_id,
BOOL from_group,
const LLUUID& to_id,
EInstantMessage im_type,
const std::string& name,
const std::string& message,
const LLUUID& id,
U32 parent_estate_id,
const LLUUID& region_id,
const LLVector3& position,
LLSD data,
U8 offline,
U32 timestamp,
EIMSource source,
S32 ttl) :
mFromID(from_id),
mFromGroup(from_group),
mToID(to_id),
mParentEstateID(0),
mRegionID(region_id),
mPosition(position),
mOffline(offline),
mViewerThinksToIsOnline(false),
mIMType(im_type),
mID(id),
mTimeStamp(timestamp),
mName(name),
mMessage(message),
mData(data),
mSource(source),
mTTL(ttl)
{
}
LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
mViewerThinksToIsOnline(false),
mSource(source),
mTTL(ttl)
{
unpackMessageBlock(msg);
}
LLIMInfo::~LLIMInfo()
{
}
void LLIMInfo::packInstantMessage(LLMessageSystem* msg) const
{
LL_DEBUGS() << "LLIMInfo::packInstantMessage()" << LL_ENDL;
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
packMessageBlock(msg);
}
void LLIMInfo::packMessageBlock(LLMessageSystem* msg) const
{
// Construct binary bucket
std::vector<U8> bucket;
if (mData.has("binary_bucket"))
{
bucket = mData["binary_bucket"].asBinary();
}
pack_instant_message_block(
msg,
mFromID,
mFromGroup,
LLUUID::null,
mToID,
mName,
mMessage,
mOffline,
mIMType,
mID,
mParentEstateID,
mRegionID,
mPosition,
mTimeStamp,
&bucket[0],
bucket.size());
}
void pack_instant_message( void pack_instant_message(
LLMessageSystem* msg, LLMessageSystem* msg,
const LLUUID& from_id, const LLUUID& from_id,
@@ -264,124 +167,3 @@ void pack_instant_message_block(
} }
msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size); msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size);
} }
void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)
{
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, mFromID);
msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, mFromGroup);
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, mToID);
msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, mParentEstateID);
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, mRegionID);
msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, mPosition);
msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, mOffline);
U8 dialog;
msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, dialog);
mIMType = (EInstantMessage) dialog;
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, mID);
msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, mTimeStamp);
msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, mName);
msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, mMessage);
S32 binary_bucket_size = llmin(
MTUBYTES,
msg->getSizeFast(
_PREHASH_MessageBlock,
_PREHASH_BinaryBucket));
if(binary_bucket_size > 0)
{
std::vector<U8> bucket;
bucket.resize(binary_bucket_size);
msg->getBinaryDataFast(
_PREHASH_MessageBlock,
_PREHASH_BinaryBucket,
&bucket[0],
0,
0,
binary_bucket_size);
mData["binary_bucket"] = bucket;
}
else
{
mData.clear();
}
}
LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
{
LLSD param_version;
param_version["version"] = 1;
LLSD param_message;
param_message["from_id"] = im_info->mFromID;
param_message["from_group"] = im_info->mFromGroup;
param_message["to_id"] = im_info->mToID;
param_message["from_name"] = im_info->mName;
param_message["message"] = im_info->mMessage;
param_message["type"] = (S32)im_info->mIMType;
param_message["id"] = im_info->mID;
param_message["timestamp"] = (S32)im_info->mTimeStamp;
param_message["offline"] = (S32)im_info->mOffline;
param_message["parent_estate_id"] = (S32)im_info->mParentEstateID;
param_message["region_id"] = im_info->mRegionID;
param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
param_message["data"] = im_info->mData;
param_message["source"]= im_info->mSource;
param_message["ttl"] = im_info->mTTL;
LLSD param_agent;
param_agent["agent_id"] = im_info->mFromID;
LLSD params;
params["version_params"] = param_version;
params["message_params"] = param_message;
params["agent_params"] = param_agent;
return params;
}
LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
{
LLSD param_message = im_info_sd["message_params"];
LLSD param_agent = im_info_sd["agent_params"];
LLPointer<LLIMInfo> im_info = new LLIMInfo(
param_message["from_id"].asUUID(),
param_message["from_group"].asBoolean(),
param_message["to_id"].asUUID(),
(EInstantMessage) param_message["type"].asInteger(),
param_message["from_name"].asString(),
param_message["message"].asString(),
param_message["id"].asUUID(),
(U32) param_message["parent_estate_id"].asInteger(),
param_message["region_id"].asUUID(),
ll_vector3_from_sd(param_message["position"]),
param_message["data"],
(U8) param_message["offline"].asInteger(),
(U32) param_message["timestamp"].asInteger(),
(EIMSource)param_message["source"].asInteger(),
param_message["ttl"].asInteger());
return im_info;
}
LLPointer<LLIMInfo> LLIMInfo::clone()
{
return new LLIMInfo(
mFromID,
mFromGroup,
mToID,
mIMType,
mName,
mMessage,
mID,
mParentEstateID,
mRegionID,
mPosition,
mData,
mOffline,
mTimeStamp,
mSource,
mTTL);
}

View File

@@ -225,62 +225,6 @@ extern const std::string INTERACTIVE_SYSTEM_FROM;
// Number of retry attempts on sending the im. // Number of retry attempts on sending the im.
extern const S32 IM_TTL; extern const S32 IM_TTL;
class LLIMInfo : public LLRefCount
{
protected:
LLIMInfo();
~LLIMInfo();
public:
LLIMInfo(LLMessageSystem* msg,
EIMSource source = IM_FROM_SIM,
S32 ttl = IM_TTL);
LLIMInfo(
const LLUUID& from_id,
BOOL from_group,
const LLUUID& to_id,
EInstantMessage im_type,
const std::string& name,
const std::string& message,
const LLUUID& id,
U32 parent_estate_id,
const LLUUID& region_id,
const LLVector3& position,
LLSD data,
U8 offline,
U32 timestamp,
EIMSource source,
S32 ttl = IM_TTL);
void packInstantMessage(LLMessageSystem* msg) const;
void packMessageBlock(LLMessageSystem* msg) const;
void unpackMessageBlock(LLMessageSystem* msg);
LLPointer<LLIMInfo> clone();
public:
LLUUID mFromID;
BOOL mFromGroup;
LLUUID mToID;
U32 mParentEstateID;
LLUUID mRegionID;
LLVector3 mPosition;
U8 mOffline;
bool mViewerThinksToIsOnline;
EInstantMessage mIMType;
LLUUID mID;
U32 mTimeStamp;
std::string mName;
std::string mMessage;
LLSD mData;
EIMSource mSource;
S32 mTTL;
};
LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd);
LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info);
void pack_instant_message( void pack_instant_message(
LLMessageSystem* msgsystem, LLMessageSystem* msgsystem,
const LLUUID& from_id, const LLUUID& from_id,

View File

@@ -207,6 +207,7 @@ void LLPrefsAscentSys::refreshValues()
mDisplayScriptJumps = gSavedSettings.getBOOL("AscentDisplayTotalScriptJumps"); mDisplayScriptJumps = gSavedSettings.getBOOL("AscentDisplayTotalScriptJumps");
mNumScriptDiff = gSavedSettings.getF32("Ascentnumscriptdiff"); mNumScriptDiff = gSavedSettings.getF32("Ascentnumscriptdiff");
mReplaceLinks = gSavedSettings.getBOOL("SinguReplaceLinks"); mReplaceLinks = gSavedSettings.getBOOL("SinguReplaceLinks");
mEmergencySeconds = gSavedPerAccountSettings.getU32("EmergencyTeleportSeconds");
mLandmark = gSavedPerAccountSettings.getString("EmergencyTeleportLandmark"); mLandmark = gSavedPerAccountSettings.getString("EmergencyTeleportLandmark");
mLandmarkBackup = gSavedPerAccountSettings.getString("EmergencyTeleportLandmarkBackup"); mLandmarkBackup = gSavedPerAccountSettings.getString("EmergencyTeleportLandmarkBackup");
@@ -353,6 +354,7 @@ void LLPrefsAscentSys::cancel()
gSavedSettings.setBOOL("AscentDisplayTotalScriptJumps", mDisplayScriptJumps); gSavedSettings.setBOOL("AscentDisplayTotalScriptJumps", mDisplayScriptJumps);
gSavedSettings.setF32("Ascentnumscriptdiff", mNumScriptDiff); gSavedSettings.setF32("Ascentnumscriptdiff", mNumScriptDiff);
gSavedSettings.setBOOL("SinguReplaceLinks", mReplaceLinks); gSavedSettings.setBOOL("SinguReplaceLinks", mReplaceLinks);
gSavedPerAccountSettings.setU32("EmergencyTeleportSeconds", mEmergencySeconds);
gSavedPerAccountSettings.setString("EmergencyTeleportLandmark", mLandmark); gSavedPerAccountSettings.setString("EmergencyTeleportLandmark", mLandmark);
gSavedPerAccountSettings.setString("EmergencyTeleportLandmarkBackup", mLandmarkBackup); gSavedPerAccountSettings.setString("EmergencyTeleportLandmarkBackup", mLandmarkBackup);

View File

@@ -118,6 +118,7 @@ private:
bool mDisplayScriptJumps; bool mDisplayScriptJumps;
bool mReplaceLinks; bool mReplaceLinks;
F32 mNumScriptDiff; F32 mNumScriptDiff;
U32 mEmergencySeconds;
std::string mLandmark; std::string mLandmark;
std::string mLandmarkBackup; std::string mLandmarkBackup;

View File

@@ -163,10 +163,11 @@ Wavefront::Wavefront(LLFace* face, LLPolyMesh* mesh, const LLXform* transform, c
if (transform_normals) Transform(normals, transform_normals); if (transform_normals) Transform(normals, transform_normals);
const U32 pcount = mesh ? mesh->getNumFaces() : (vb->getNumIndices()/3); //indices const U32 pcount = mesh ? mesh->getNumFaces() : (vb->getNumIndices()/3); //indices
const U16 offset = face->getIndicesStart(); //indices const U32 offset = face->getIndicesStart(); //indices
for (U32 i = 0; i < pcount; ++i) for (U32 i = 0; i < pcount; ++i)
{ {
triangles.push_back(tri(getIndices[i * 3 + offset] + start, getIndices[i * 3 + 1 + offset] + start, getIndices[i * 3 + 2 + offset] + start)); const auto off = i * 3 + offset;
triangles.push_back(tri(getIndices[off] + start, getIndices[off + 1] + start, getIndices[off + 2] + start));
} }
} }
@@ -174,9 +175,9 @@ void Wavefront::Transform(vert_t& v, const LLXform* x) //recursive
{ {
LLMatrix4 m; LLMatrix4 m;
x->getLocalMat4(m); x->getLocalMat4(m);
for (vert_t::iterator iterv = v.begin(); iterv != v.end(); ++iterv) for (auto& i : v)
{ {
iterv->first = iterv->first * m; i.first = i.first * m;
} }
if (const LLXform* xp = x->getParent()) Transform(v, xp); if (const LLXform* xp = x->getParent()) Transform(v, xp);
@@ -186,9 +187,9 @@ void Wavefront::Transform(vec3_t& v, const LLXform* x) //recursive
{ {
LLMatrix4 m; LLMatrix4 m;
x->getLocalMat4(m); x->getLocalMat4(m);
for (vec3_t::iterator iterv = v.begin(); iterv != v.end(); ++iterv) for (auto& i : v)
{ {
*iterv = *iterv * m; i = i * m;
} }
if (const LLXform* xp = x->getParent()) Transform(v, xp); if (const LLXform* xp = x->getParent()) Transform(v, xp);
@@ -252,9 +253,9 @@ namespace
asset_id_matches); asset_id_matches);
// See if any of the inventory items matching this sculpt id are exportable // See if any of the inventory items matching this sculpt id are exportable
for (U32 i = 0; i < items.size(); i++) for (const auto& item : items)
{ {
const LLPermissions item_permissions = items[i]->getPermissions(); const LLPermissions item_permissions = item->getPermissions();
if (item_permissions.allowExportBy(gAgentID, LFSimFeatureHandler::instance().exportPolicy())) if (item_permissions.allowExportBy(gAgentID, LFSimFeatureHandler::instance().exportPolicy()))
{ {
return true; return true;
@@ -269,9 +270,9 @@ namespace
} }
} }
class LFSaveSelectedObjects : public view_listener_t class LFSaveSelectedObjects final : public view_listener_t
{ {
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) override
{ {
if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection()) if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection())
{ {
@@ -288,10 +289,10 @@ namespace
S32 included = 0; S32 included = 0;
for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end(); ++iter) for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end(); ++iter)
{ {
total++; ++total;
LLSelectNode* node = *iter; LLSelectNode* node = *iter;
if (!can_export_node(node)) continue; if (!can_export_node(node)) continue;
included++; ++included;
wfsaver->Add(node->getObject()); wfsaver->Add(node->getObject());
} }
if (wfsaver->obj_v.empty()) if (wfsaver->obj_v.empty())
@@ -322,12 +323,12 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
{ {
offset = -av_vo->getRenderPosition(); offset = -av_vo->getRenderPosition();
avatar_joint_list_t vjv = av_vo->mMeshLOD; avatar_joint_list_t vjv = av_vo->mMeshLOD;
for (avatar_joint_list_t::const_iterator itervj = vjv.begin(); itervj != vjv.end(); ++itervj) for (const auto& itervj : vjv)
{ {
const LLViewerJoint* vj = dynamic_cast<LLViewerJoint*>(*itervj); const auto* vj = dynamic_cast<const LLViewerJoint*>(itervj);
if (!vj || vj->mMeshParts.empty()) continue; if (!vj || vj->mMeshParts.empty()) continue;
LLViewerJointMesh* vjm = dynamic_cast<LLViewerJointMesh*>(vj->mMeshParts[0]); //highest LOD auto* vjm = dynamic_cast<LLViewerJointMesh*>(vj->mMeshParts[0]); //highest LOD
if (!vjm) continue; if (!vjm) continue;
vjm->updateJointGeometry(); vjm->updateJointGeometry();
@@ -355,21 +356,19 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
Add(Wavefront(face, pm, NULL, &normfix)); Add(Wavefront(face, pm, NULL, &normfix));
} }
for (LLVOAvatar::attachment_map_t::const_iterator iter = av_vo->mAttachmentPoints.begin(); iter != av_vo->mAttachmentPoints.end(); ++iter) for (const auto& ap : av_vo->mAttachmentPoints)
{ {
LLViewerJointAttachment* ja = iter->second; LLViewerJointAttachment* ja = ap.second;
if (!ja) continue; if (!ja) continue;
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator itero = ja->mAttachedObjects.begin(); itero != ja->mAttachedObjects.end(); ++itero) for (const auto& o : ja->mAttachedObjects)
{ {
LLViewerObject* o = *itero;
if (!o) continue; if (!o) continue;
std::vector<LLViewerObject*> prims; std::vector<LLViewerObject*> prims;
o->addThisAndAllChildren(prims); o->addThisAndAllChildren(prims);
for (std::vector<LLViewerObject* >::iterator iterc = prims.begin(); iterc != prims.end(); ++iterc) for (const auto& c : prims)
{ {
const LLViewerObject* c = *iterc;
if (!c) continue; if (!c) continue;
if (LLSelectNode* n = LLSelectMgr::getInstance()->getSelection()->findNode(const_cast<LLViewerObject*>(c))) if (LLSelectNode* n = LLSelectMgr::getInstance()->getSelection()->findNode(const_cast<LLViewerObject*>(c)))
{ {
@@ -400,9 +399,9 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
} }
namespace namespace
{ {
class LFSaveSelectedAvatar : public view_listener_t class LFSaveSelectedAvatar final : public view_listener_t
{ {
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) override
{ {
if (const LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())) if (const LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()))
{ {
@@ -446,49 +445,48 @@ bool WavefrontSaver::saveFile(LLFILE* fp)
int num = 0; int num = 0;
int index = 0; int index = 0;
for (std::vector<Wavefront>::iterator w_iter = obj_v.begin(); w_iter != obj_v.end(); ++w_iter) for (const auto& obj : obj_v)
{ {
int count = 0; int count = 0;
std::string name = (*w_iter).name; std::string name = obj.name;
if (name.empty()) name = llformat("%d", num++); if (name.empty()) name = llformat("%d", num++);
vert_t vertices = (*w_iter).vertices; auto& vertices = obj.vertices;
vec3_t normals = (*w_iter).normals; auto& normals = obj.normals;
tri_t triangles = (*w_iter).triangles; auto& triangles = obj.triangles;
//Write Object //Write Object
write_or_bust(fp, "o " + name + "\n"); write_or_bust(fp, "o " + name + '\n');
//Write vertices; swap axes if necessary //Write vertices; swap axes if necessary
static const LLCachedControl<bool> swapYZ("OBJExportSwapYZ", false); static const LLCachedControl<bool> swapYZ("OBJExportSwapYZ", false);
const double xm = swapYZ ? -1.0 : 1.0; const double xm = swapYZ ? -1.0 : 1.0;
const int y = swapYZ ? 2 : 1; const int y = swapYZ ? 2 : 1;
const int z = swapYZ ? 1 : 2; const int z = swapYZ ? 1 : 2;
for (vert_t::iterator v_iter = vertices.begin(); v_iter != vertices.end(); ++v_iter) for (const auto& vert : vertices)
{ {
++count; ++count;
const LLVector3 v = v_iter->first + offset; const LLVector3 v = vert.first + offset;
write_or_bust(fp, llformat("v %f %f %f\n",v[0] * xm, v[y], v[z])); write_or_bust(fp, llformat("v %f %f %f\n",v[0] * xm, v[y], v[z]));
} }
for (vec3_t::iterator n_iter = normals.begin(); n_iter != normals.end(); ++n_iter) for (const auto& n : normals)
{ {
const LLVector3 n = *n_iter;
write_or_bust(fp, llformat("vn %f %f %f\n",n[0] * xm, n[y], n[z])); write_or_bust(fp, llformat("vn %f %f %f\n",n[0] * xm, n[y], n[z]));
} }
for (vert_t::iterator v_iter = vertices.begin(); v_iter != vertices.end(); ++v_iter) for (const auto& vert : vertices)
{ {
write_or_bust(fp, llformat("vt %f %f\n", v_iter->second[0], v_iter->second[1])); write_or_bust(fp, llformat("vt %f %f\n", vert.second[0], vert.second[1]));
} }
//Write triangles //Write triangles
for (tri_t::iterator t_iter = triangles.begin(); t_iter != triangles.end(); ++t_iter) for (const auto& triangle : triangles)
{ {
const int f1 = t_iter->v0 + index + 1; const int f1 = triangle.v0 + index + 1;
const int f2 = t_iter->v1 + index + 1; const int f2 = triangle.v1 + index + 1;
const int f3 = t_iter->v2 + index + 1; const int f3 = triangle.v2 + index + 1;
write_or_bust(fp, llformat("f %d/%d/%d %d/%d/%d %d/%d/%d\n", write_or_bust(fp, llformat("f %d/%d/%d %d/%d/%d %d/%d/%d\n",
f1,f1,f1,f2,f2,f2,f3,f3,f3)); f1,f1,f1,f2,f2,f2,f3,f3,f3));
} }

View File

@@ -32,16 +32,18 @@
// library includes // library includes
#include "aifilepicker.h" #include "aifilepicker.h"
#include "llavatarnamecache.h"
#include "llnotificationsutil.h" #include "llnotificationsutil.h"
// newview includes // newview includes
#include "lfsimfeaturehandler.h" #include "lfsimfeaturehandler.h"
#include "llface.h"
#include "llvovolume.h"
#include "llviewerinventory.h"
#include "llinventorymodel.h" #include "llinventorymodel.h"
#include "llinventoryfunctions.h" #include "llinventoryfunctions.h"
#include "llface.h"
#include "llversioninfo.h"
#include "llviewerinventory.h"
#include "llviewertexturelist.h" #include "llviewertexturelist.h"
#include "llvovolume.h"
// menu includes // menu includes
#include "llevent.h" #include "llevent.h"
@@ -74,11 +76,11 @@ typedef LLMemberListener<LLView> view_listener_t;
namespace DAEExportUtil namespace DAEExportUtil
{ {
static LLUUID LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f"); const auto LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f");
static LLUUID LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f"); const auto LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f");
static LLUUID LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837"); const auto LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837");
static LLUUID LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); const auto LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903");
static LLUUID LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"); const auto LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361");
enum image_format_type enum image_format_type
{ {
@@ -105,23 +107,17 @@ namespace DAEExportUtil
// See if any of the inventory items matching this texture id are exportable // See if any of the inventory items matching this texture id are exportable
ExportPolicy policy = LFSimFeatureHandler::instance().exportPolicy(); ExportPolicy policy = LFSimFeatureHandler::instance().exportPolicy();
for (size_t i = 0; i < items.size(); i++) for (const auto& item : items)
{ {
const LLPermissions item_permissions = items[i]->getPermissions(); const LLPermissions item_permissions = item->getPermissions();
if (item_permissions.allowExportBy(gAgentID, policy)) if (item_permissions.allowExportBy(gAgentID, policy))
{ {
if (name != NULL) if (name) *name = item->getName();
{
(*name) = items[i]->getName();
}
return true; return true;
} }
} }
if (name != NULL) if (name) *name = id.getString();
{
(*name) = id.getString();
}
return (policy & ep_full_perm) == ep_full_perm; return (policy & ep_full_perm) == ep_full_perm;
} }
@@ -206,7 +202,7 @@ public:
} }
} }
BOOL postBuild() BOOL postBuild() override
{ {
mFileName = getChildView("file name editor"); mFileName = getChildView("file name editor");
mExportBtn = getChildView("export button"); mExportBtn = getChildView("export button");
@@ -306,14 +302,9 @@ public:
S32 getNumExportableTextures() S32 getNumExportableTextures()
{ {
S32 res = 0; S32 res = 0;
for (const auto& name : mSaver.mTextureNames)
for (DAESaver::string_list_t::const_iterator t = mSaver.mTextureNames.begin(); t != mSaver.mTextureNames.end(); ++t)
{ {
std::string name = *t; if (!name.empty()) ++res;
if (!name.empty())
{
++res;
}
} }
return res; return res;
@@ -365,7 +356,7 @@ public:
gIdleCallbacks.addFunction(saveTexturesWorker, this); gIdleCallbacks.addFunction(saveTexturesWorker, this);
} }
class CacheReadResponder : public LLTextureCache::ReadResponder class CacheReadResponder final : public LLTextureCache::ReadResponder
{ {
private: private:
LLPointer<LLImageFormatted> mFormattedImage; LLPointer<LLImageFormatted> mFormattedImage;
@@ -413,7 +404,7 @@ public:
mImageLocal = imagelocal; mImageLocal = imagelocal;
} }
virtual void completed(bool success) void completed(bool success) override
{ {
if (success && mFormattedImage.notNull() && mImageSize > 0) if (success && mFormattedImage.notNull() && mImageSize > 0)
{ {
@@ -546,10 +537,8 @@ void DAESaver::updateTextureInfo()
{ {
LLTextureEntry* te = obj->getTE(face_num); LLTextureEntry* te = obj->getTE(face_num);
const LLUUID id = te->getID(); const LLUUID id = te->getID();
if (std::find(mTextures.begin(), mTextures.end(), id) != mTextures.end()) if (std::find(mTextures.begin(), mTextures.end(), id) != mTextures.end()) continue;
{
continue;
}
mTextures.push_back(id); mTextures.push_back(id);
std::string name; std::string name;
if (id != DAEExportUtil::LL_TEXTURE_BLANK && DAEExportUtil::canExportTexture(id, &name)) if (id != DAEExportUtil::LL_TEXTURE_BLANK && DAEExportUtil::canExportTexture(id, &name))
@@ -566,7 +555,6 @@ void DAESaver::updateTextureInfo()
} }
} }
class v4adapt class v4adapt
{ {
private: private:
@@ -579,7 +567,7 @@ public:
} }
}; };
void DAESaver::addSource(daeElement* mesh, const char* src_id, std::string params, const std::vector<F32> &vals) void DAESaver::addSource(daeElement* mesh, const char* src_id, const std::string& params, const std::vector<F32> &vals)
{ {
daeElement* source = mesh->add("source"); daeElement* source = mesh->add("source");
source->setAttribute("id", src_id); source->setAttribute("id", src_id);
@@ -588,9 +576,9 @@ void DAESaver::addSource(daeElement* mesh, const char* src_id, std::string param
src_array->setAttribute("id", llformat("%s-%s", src_id, "array").c_str()); src_array->setAttribute("id", llformat("%s-%s", src_id, "array").c_str());
src_array->setAttribute("count", llformat("%d", vals.size()).c_str()); src_array->setAttribute("count", llformat("%d", vals.size()).c_str());
for (U32 i = 0; i < vals.size(); i++) for (const auto& val : vals)
{ {
((domFloat_array*)src_array)->getValue().append(vals[i]); static_cast<domFloat_array*>(src_array)->getValue().append(val);
} }
domAccessor* acc = daeSafeCast<domAccessor>(source->add("technique_common accessor")); domAccessor* acc = daeSafeCast<domAccessor>(source->add("technique_common accessor"));
@@ -598,10 +586,10 @@ void DAESaver::addSource(daeElement* mesh, const char* src_id, std::string param
acc->setCount(vals.size() / params.size()); acc->setCount(vals.size() / params.size());
acc->setStride(params.size()); acc->setStride(params.size());
for (std::string::iterator p_iter = params.begin(); p_iter != params.end(); ++p_iter) for (const auto& param : params)
{ {
domElement* pX = acc->add("param"); domElement* pX = acc->add("param");
pX->setAttribute("name", llformat("%c", *p_iter).c_str()); pX->setAttribute("name", (LLStringUtil::null + param).c_str());
pX->setAttribute("type", "float"); pX->setAttribute("type", "float");
} }
} }
@@ -650,7 +638,7 @@ void DAESaver::addPolygons(daeElement* mesh, const char* geomID, const char* mat
{ {
for (S32 i = 0; i < face->mNumIndices; i++) for (S32 i = 0; i < face->mNumIndices; i++)
{ {
U16 index = index_offset + face->mIndices[i]; U32 index = index_offset + face->mIndices[i];
(p->getValue()).append(index); (p->getValue()).append(index);
if (i % 3 == 0) if (i % 3 == 0)
{ {
@@ -710,11 +698,21 @@ void DAESaver::transformTexCoord(S32 num_vert, LLVector2* coord, LLVector3* posi
bool DAESaver::saveDAE(std::string filename) bool DAESaver::saveDAE(std::string filename)
{ {
// Collada expects file and folder names to be escaped
// Note: cdom::nativePathToUri()
// Same as in LLDAELoader::OpenFile()
const char* allowed =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"%-._~:\"|\\/";
std::string uri_filename = LLURI::escape(filename, allowed);
mAllMaterials.clear(); mAllMaterials.clear();
mTotalNumMaterials = 0; mTotalNumMaterials = 0;
DAE dae; DAE dae;
// First set the filename to save // First set the filename to save
daeElement* root = dae.add(filename); daeElement* root = dae.add(uri_filename);
// Obligatory elements in header // Obligatory elements in header
daeElement* asset = root->add("asset"); daeElement* asset = root->add("asset");
@@ -734,9 +732,13 @@ bool DAESaver::saveDAE(std::string filename)
up_axis->setCharData("Z_UP"); up_axis->setCharData("Z_UP");
// File creator // File creator
std::string author;
if (!LLAvatarNameCache::getNSName(gAgentID, author))
author = "Unknown";
daeElement* contributor = asset->add("contributor"); daeElement* contributor = asset->add("contributor");
contributor->add("author")->setCharData(LLAppViewer::instance()->getSecondLifeTitle() + " User"); contributor->add("author")->setCharData(author);
contributor->add("authoring_tool")->setCharData(LLAppViewer::instance()->getSecondLifeTitle() + " Collada Export"); contributor->add("authoring_tool")->setCharData(LLVersionInfo::getChannelAndVersion() + " Collada Export");
daeElement* images = root->add("library_images"); daeElement* images = root->add("library_images");
daeElement* geomLib = root->add("library_geometries"); daeElement* geomLib = root->add("library_geometries");
@@ -825,7 +827,6 @@ bool DAESaver::saveDAE(std::string filename)
} }
} }
addSource(mesh, llformat("%s-%s", geomID, "positions").c_str(), "XYZ", position_data); addSource(mesh, llformat("%s-%s", geomID, "positions").c_str(), "XYZ", position_data);
addSource(mesh, llformat("%s-%s", geomID, "normals").c_str(), "XYZ", normal_data); addSource(mesh, llformat("%s-%s", geomID, "normals").c_str(), "XYZ", normal_data);
addSource(mesh, llformat("%s-%s", geomID, "map0").c_str(), "ST", uv_data); addSource(mesh, llformat("%s-%s", geomID, "map0").c_str(), "ST", uv_data);
@@ -845,12 +846,11 @@ bool DAESaver::saveDAE(std::string filename)
// Add triangles // Add triangles
if (gSavedSettings.getBOOL("DAEExportConsolidateMaterials")) if (gSavedSettings.getBOOL("DAEExportConsolidateMaterials"))
{ {
for (U32 objMaterial = 0; objMaterial < objMaterials.size(); objMaterial++) for (const auto& objMaterial : objMaterials)
{ {
int_list_t faces; int_list_t faces;
getFacesWithMaterial(obj, objMaterials[objMaterial], &faces); getFacesWithMaterial(obj, objMaterial, &faces);
std::string matName = objMaterials[objMaterial].name; addPolygons(mesh, geomID, (objMaterial.name + "-material").c_str(), obj, &faces);
addPolygons(mesh, geomID, (matName + "-material").c_str(), obj, &faces);
} }
} }
else else
@@ -888,12 +888,12 @@ bool DAESaver::saveDAE(std::string filename)
// Bind materials // Bind materials
daeElement* tq = nodeGeometry->add("bind_material technique_common"); daeElement* tq = nodeGeometry->add("bind_material technique_common");
for (U32 objMaterial = 0; objMaterial < objMaterials.size(); objMaterial++) for (const auto& objMaterial : objMaterials)
{ {
std::string matName = objMaterials[objMaterial].name;
daeElement* instanceMaterial = tq->add("instance_material"); daeElement* instanceMaterial = tq->add("instance_material");
instanceMaterial->setAttribute("symbol", (matName + "-material").c_str()); std::string matName = objMaterial.name + "-material";
instanceMaterial->setAttribute("target", ("#" + matName + "-material").c_str()); instanceMaterial->setAttribute("symbol", matName.c_str());
instanceMaterial->setAttribute("target", ('#' + matName).c_str());
} }
nodeGeometry->setAttribute("url", llformat("#%s-%s", geomID, "mesh").c_str()); nodeGeometry->setAttribute("url", llformat("#%s-%s", geomID, "mesh").c_str());
@@ -904,12 +904,12 @@ bool DAESaver::saveDAE(std::string filename)
generateEffects(effects); generateEffects(effects);
// Materials // Materials
for (U32 objMaterial = 0; objMaterial < mAllMaterials.size(); objMaterial++) for (const auto& objMaterial : mAllMaterials)
{ {
daeElement* mat = materials->add("material"); daeElement* mat = materials->add("material");
mat->setAttribute("id", (mAllMaterials[objMaterial].name + "-material").c_str()); mat->setAttribute("id", (objMaterial.name + "-material").c_str());
daeElement* matEffect = mat->add("instance_effect"); daeElement* matEffect = mat->add("instance_effect");
matEffect->setAttribute("url", ("#" + mAllMaterials[objMaterial].name + "-fx").c_str()); matEffect->setAttribute("url", ('#' + objMaterial.name + "-fx").c_str());
} }
root->add("scene instance_visual_scene")->setAttribute("url", "#Scene"); root->add("scene instance_visual_scene")->setAttribute("url", "#Scene");
@@ -930,11 +930,11 @@ DAESaver::MaterialInfo DAESaver::getMaterial(LLTextureEntry* te)
{ {
if (gSavedSettings.getBOOL("DAEExportConsolidateMaterials")) if (gSavedSettings.getBOOL("DAEExportConsolidateMaterials"))
{ {
for (U32 i=0; i < mAllMaterials.size(); i++) for (const auto& mat : mAllMaterials)
{ {
if (mAllMaterials[i].matches(te)) if (mat.matches(te))
{ {
return mAllMaterials[i]; return mat;
} }
} }
} }
@@ -944,7 +944,7 @@ DAESaver::MaterialInfo DAESaver::getMaterial(LLTextureEntry* te)
ret.color = te->getColor(); ret.color = te->getColor();
ret.name = llformat("Material%d", mAllMaterials.size()); ret.name = llformat("Material%d", mAllMaterials.size());
mAllMaterials.push_back(ret); mAllMaterials.push_back(ret);
return mAllMaterials[mAllMaterials.size() - 1]; return ret;
} }
void DAESaver::getMaterials(LLViewerObject* obj, material_list_t* ret) void DAESaver::getMaterials(LLViewerObject* obj, material_list_t* ret)
@@ -954,10 +954,7 @@ void DAESaver::getMaterials(LLViewerObject* obj, material_list_t* ret)
{ {
LLTextureEntry* te = obj->getTE(face_num); LLTextureEntry* te = obj->getTE(face_num);
if (skipFace(te)) if (skipFace(te)) continue;
{
continue;
}
MaterialInfo mat = getMaterial(te); MaterialInfo mat = getMaterial(te);
@@ -968,7 +965,7 @@ void DAESaver::getMaterials(LLViewerObject* obj, material_list_t* ret)
} }
} }
void DAESaver::getFacesWithMaterial(LLViewerObject* obj, MaterialInfo& mat, int_list_t* ret) void DAESaver::getFacesWithMaterial(LLViewerObject* obj, const MaterialInfo& mat, int_list_t* ret)
{ {
S32 num_faces = obj->getVolume()->getNumVolumeFaces(); S32 num_faces = obj->getVolume()->getNumVolumeFaces();
for (S32 face_num = 0; face_num < num_faces; ++face_num) for (S32 face_num = 0; face_num < num_faces; ++face_num)
@@ -985,11 +982,11 @@ void DAESaver::generateEffects(daeElement *effects)
// Effects (face color, alpha) // Effects (face color, alpha)
bool export_textures = gSavedSettings.getBOOL("DAEExportTextures"); bool export_textures = gSavedSettings.getBOOL("DAEExportTextures");
for (U32 mat = 0; mat < mAllMaterials.size(); mat++) for (const auto& mat : mAllMaterials)
{ {
LLColor4 color = mAllMaterials[mat].color; LLColor4 color = mat.color;
domEffect* effect = (domEffect*)effects->add("effect"); domEffect* effect = (domEffect*)effects->add("effect");
effect->setId((mAllMaterials[mat].name + "-fx").c_str()); effect->setId((mat.name + "-fx").c_str());
daeElement* profile = effect->add("profile_COMMON"); daeElement* profile = effect->add("profile_COMMON");
std::string colladaName; std::string colladaName;
@@ -999,7 +996,7 @@ void DAESaver::generateEffects(daeElement *effects)
U32 i = 0; U32 i = 0;
for (; i < mTextures.size(); i++) for (; i < mTextures.size(); i++)
{ {
if (mAllMaterials[mat].textureID == mTextures[i]) if (mat.textureID == mTextures[i])
{ {
textID = mTextures[i]; textID = mTextures[i];
break; break;
@@ -1043,19 +1040,18 @@ void DAESaver::generateEffects(daeElement *effects)
void DAESaver::generateImagesSection(daeElement* images) void DAESaver::generateImagesSection(daeElement* images)
{ {
for (U32 i=0; i < mTextureNames.size(); i++) for (const auto& name : mTextureNames)
{ {
std::string name = mTextureNames[i];
if (name.empty()) continue; if (name.empty()) continue;
std::string colladaName = name + "_" + mImageFormat; std::string colladaName = name + '_' + mImageFormat;
daeElement* image = images->add("image"); daeElement* image = images->add("image");
image->setAttribute("id", colladaName.c_str()); image->setAttribute("id", colladaName.c_str());
image->setAttribute("name", colladaName.c_str()); image->setAttribute("name", colladaName.c_str());
image->add("init_from")->setCharData(LLURI::escape(name + "." + mImageFormat)); image->add("init_from")->setCharData(LLURI::escape(name + '.' + mImageFormat));
} }
} }
class DAESaveSelectedObjects : public view_listener_t class DAESaveSelectedObjects final : public view_listener_t
{ {
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{ {

View File

@@ -33,50 +33,29 @@ class LLViewerObject;
class DAESaver class DAESaver
{ {
public: public:
class MaterialInfo struct MaterialInfo
{ {
public:
LLUUID textureID; LLUUID textureID;
LLColor4 color; LLColor4 color;
std::string name; std::string name;
bool matches(LLTextureEntry* te) bool matches(LLTextureEntry* te) const
{ {
return (textureID == te->getID()) && (color == te->getColor()); return (textureID == te->getID()) && (color == te->getColor());
} }
bool operator== (const MaterialInfo& rhs) bool operator== (const MaterialInfo& rhs) const
{ {
return (textureID == rhs.textureID) && (color == rhs.color) && (name == rhs.name); return (textureID == rhs.textureID) && (color == rhs.color) && (name == rhs.name);
} }
bool operator!= (const MaterialInfo& rhs) bool operator!= (const MaterialInfo& rhs) const
{ {
return !(*this == rhs); return !(*this == rhs);
} }
MaterialInfo()
{
}
MaterialInfo(const MaterialInfo& rhs)
{
textureID = rhs.textureID;
color = rhs.color;
name = rhs.name;
}
MaterialInfo& operator= (const MaterialInfo& rhs)
{
textureID = rhs.textureID;
color = rhs.color;
name = rhs.name;
return *this;
}
}; };
typedef std::vector<std::pair<LLViewerObject*,std::string> > obj_info_t; typedef std::vector<std::pair<LLViewerObject*,std::string>> obj_info_t;
typedef uuid_vec_t id_list_t; typedef uuid_vec_t id_list_t;
typedef std::vector<std::string> string_list_t; typedef std::vector<std::string> string_list_t;
typedef std::vector<S32> int_list_t; typedef std::vector<S32> int_list_t;
@@ -97,12 +76,12 @@ public:
private: private:
void transformTexCoord(S32 num_vert, LLVector2* coord, LLVector3* positions, LLVector3* normals, LLTextureEntry* te, LLVector3 scale); void transformTexCoord(S32 num_vert, LLVector2* coord, LLVector3* positions, LLVector3* normals, LLTextureEntry* te, LLVector3 scale);
void addSource(daeElement* mesh, const char* src_id, std::string params, const std::vector<F32> &vals); void addSource(daeElement* mesh, const char* src_id, const std::string& params, const std::vector<F32> &vals);
void addPolygons(daeElement* mesh, const char* geomID, const char* materialID, LLViewerObject* obj, int_list_t* faces_to_include); void addPolygons(daeElement* mesh, const char* geomID, const char* materialID, LLViewerObject* obj, int_list_t* faces_to_include);
bool skipFace(LLTextureEntry *te); bool skipFace(LLTextureEntry *te);
MaterialInfo getMaterial(LLTextureEntry* te); MaterialInfo getMaterial(LLTextureEntry* te);
void getMaterials(LLViewerObject* obj, material_list_t* ret); void getMaterials(LLViewerObject* obj, material_list_t* ret);
void getFacesWithMaterial(LLViewerObject* obj, MaterialInfo& mat, int_list_t* ret); void getFacesWithMaterial(LLViewerObject* obj, const MaterialInfo& mat, int_list_t* ret);
void generateEffects(daeElement *effects); void generateEffects(daeElement *effects);
void generateImagesSection(daeElement* images); void generateImagesSection(daeElement* images);
}; };

View File

@@ -40,11 +40,21 @@
/// Classes for AISv3 support. /// Classes for AISv3 support.
///---------------------------------------------------------------------------- ///----------------------------------------------------------------------------
extern AIHTTPTimeoutPolicy AISAPIResponder_timeout;
class AISCommand final : public LLHTTPClient::ResponderWithCompleted class AISCommand final : public LLHTTPClient::ResponderWithCompleted
{ {
public: public:
typedef boost::function<void()> command_func_type; typedef boost::function<void()> command_func_type;
// AISCommand - base class for retry-able HTTP requests using the AISv3 cap. // AISCommand - base class for retry-able HTTP requests using the AISv3 cap.
// Limit max in flight requests to 2. Server was aggressively throttling otherwise.
constexpr static U8 sMaxActiveAISCommands = 4;
static U8 sActiveAISCommands;
static std::queue< boost::intrusive_ptr< AISCommand > > sPendingAISCommands;
virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return AISAPIResponder_timeout; }
AISCommand(AISAPI::COMMAND_TYPE type, const char* name, const LLUUID& targetId, AISAPI::completion_t callback) : AISCommand(AISAPI::COMMAND_TYPE type, const char* name, const LLUUID& targetId, AISAPI::completion_t callback) :
mCommandFunc(NULL), mCommandFunc(NULL),
mRetryPolicy(new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10)), mRetryPolicy(new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10)),
@@ -53,10 +63,30 @@ public:
mName(name), mName(name),
mType(type) mType(type)
{} {}
virtual ~AISCommand()
{
if (mActive)
{
--sActiveAISCommands;
while (sActiveAISCommands < sMaxActiveAISCommands && !sPendingAISCommands.empty())
{
sPendingAISCommands.front()->dispatch();
sPendingAISCommands.pop();
}
}
}
void run( command_func_type func ) void run( command_func_type func )
{ {
(mCommandFunc = func)(); mCommandFunc = func;
if (sActiveAISCommands >= sMaxActiveAISCommands)
{
sPendingAISCommands.push(this);
}
else
{
dispatch();
}
} }
char const* getName(void) const override char const* getName(void) const override
@@ -64,6 +94,17 @@ public:
return mName; return mName;
} }
private:
void dispatch()
{
if (LLApp::isQuitting())
{
return;
}
++sActiveAISCommands;
mActive = true;
(mCommandFunc)();
}
void markComplete() void markComplete()
{ {
// Command func holds a reference to self, need to release it // Command func holds a reference to self, need to release it
@@ -72,42 +113,56 @@ public:
mRetryPolicy->onSuccess(); mRetryPolicy->onSuccess();
} }
void malformedResponse() { mStatus = HTTP_INTERNAL_ERROR_OTHER; mReason = llformat("Malformed response contents (original code: %d)", mStatus); }
bool onFailure() bool onFailure()
{ {
bool retry = mStatus != HTTP_INTERNAL_ERROR_OTHER && mStatus != 410; // We handle these and stop mRetryPolicy->onFailure(mStatus, getResponseHeaders());
LL_WARNS("Inventory") << "Inventory error: " << dumpResponse() << LL_ENDL;
if (retry) mRetryPolicy->onFailure(mStatus, getResponseHeaders());
F32 seconds_to_wait; F32 seconds_to_wait;
if (retry && mRetryPolicy->shouldRetry(seconds_to_wait)) if (mRetryPolicy->shouldRetry(seconds_to_wait))
{ {
if (mStatus == 503)
{
// Pad delay a bit more since we're getting throttled.
seconds_to_wait += 10.f + ll_frand(4.f);
}
LL_WARNS("Inventory") << "Retrying in " << seconds_to_wait << "seconds due to inventory error for " << getName() <<": " << dumpResponse() << LL_ENDL;
doAfterInterval(mCommandFunc,seconds_to_wait); doAfterInterval(mCommandFunc,seconds_to_wait);
return true;
} }
else else
{ {
// Command func holds a reference to self, need to release it // Command func holds a reference to self, need to release it
// after a success or final failure. // after a success or final failure.
// *TODO: Notify user? This seems bad. // *TODO: Notify user? This seems bad.
LL_WARNS("Inventory") << "Abort due to inventory error for " << getName() <<": " << dumpResponse() << LL_ENDL;
mCommandFunc = no_op; mCommandFunc = no_op;
return false;
} }
return retry;
} }
protected: protected:
void httpCompleted() override void httpCompleted() override
{ {
AISAPI::InvokeAISCommandCoro(this, getURL(), mTargetId, getContent(), mCompletionFunc, (AISAPI::COMMAND_TYPE)mType); // Continue through if successful or longer retrying,
if (isGoodStatus(mStatus) || !onFailure())
{
markComplete();
AISAPI::InvokeAISCommandCoro(this, getURL(), mTargetId, getContent(), mCompletionFunc, (AISAPI::COMMAND_TYPE)mType);
}
} }
private:
command_func_type mCommandFunc; command_func_type mCommandFunc;
LLPointer<LLHTTPRetryPolicy> mRetryPolicy; LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
AISAPI::completion_t mCompletionFunc; AISAPI::completion_t mCompletionFunc;
const LLUUID mTargetId; const LLUUID mTargetId;
const char* mName; const char* mName;
bool mActive = false;
AISAPI::COMMAND_TYPE mType; AISAPI::COMMAND_TYPE mType;
}; };
U8 AISCommand::sActiveAISCommands = 0;
std::queue< boost::intrusive_ptr< AISCommand > > AISCommand::sPendingAISCommands;
//========================================================================= //=========================================================================
const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3"); const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3");
const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3"); const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3");
@@ -312,21 +367,18 @@ void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t
boost::intrusive_ptr< AISCommand > responder = new AISCommand(UPDATEITEM, "UpdateItem",itemId, callback); boost::intrusive_ptr< AISCommand > responder = new AISCommand(UPDATEITEM, "UpdateItem",itemId, callback);
responder->run(boost::bind(&LLHTTPClient::patch, url, updates, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, (AIStateMachine*)NULL, 0)); responder->run(boost::bind(&LLHTTPClient::patch, url, updates, responder/*,*/ DEBUG_CURLIO_PARAM(debug_off), keep_alive, (AIStateMachine*)NULL, 0));
} }
void AISAPI::InvokeAISCommandCoro(AISCommand* responder, void AISAPI::InvokeAISCommandCoro(LLHTTPClient::ResponderWithCompleted* responder,
std::string url, std::string url,
LLUUID targetId, LLSD result, completion_t callback, COMMAND_TYPE type) LLUUID targetId, LLSD result, completion_t callback, COMMAND_TYPE type)
{ {
LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL;
auto status = responder->getStatus(); auto status = responder->getStatus();
if (!responder->isGoodStatus(status) || !result.isMap()) if (!responder->isGoodStatus(status) || !result.isMap())
{ {
if (!result.isMap()) LL_WARNS("Inventory") << "Inventory error: " << status << ": " << responder->getReason() << LL_ENDL;
{ if (status == 410) //GONE
responder->malformedResponse();
}
else if (status == 410) //GONE
{ {
// Item does not exist or was already deleted from server. // Item does not exist or was already deleted from server.
// parent folder is out of sync // parent folder is out of sync
@@ -360,11 +412,12 @@ void AISAPI::InvokeAISCommandCoro(AISCommand* responder,
} }
} }
} }
// Keep these statuses accounted for in the responder too if (!result.isMap())
if (responder->onFailure()) // If we're retrying, exit early. {
return; LL_WARNS("Inventory") << "Inventory error: Malformed response contents" << LL_ENDL;
}
LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL;
} }
else responder->markComplete();
gInventory.onAISUpdateReceived("AISCommand", result); gInventory.onAISUpdateReceived("AISCommand", result);

View File

@@ -72,7 +72,7 @@ private:
static std::string getInvCap(); static std::string getInvCap();
static std::string getLibCap(); static std::string getLibCap();
static void InvokeAISCommandCoro(class AISCommand* responder, static void InvokeAISCommandCoro(LLHTTPClient::ResponderWithCompleted* responder,
std::string url, LLUUID targetId, LLSD body, std::string url, LLUUID targetId, LLSD body,
completion_t callback, COMMAND_TYPE type); completion_t callback, COMMAND_TYPE type);
}; };

View File

@@ -235,7 +235,7 @@ struct crashpad_annotation : public crashpad::Annotation {
crashpad_annotation(const char* name) : crashpad::Annotation(T, name, buffer.data()) crashpad_annotation(const char* name) : crashpad::Annotation(T, name, buffer.data())
{} {}
void set(const std::string& src) { void set(const std::string& src) {
LL_INFOS() << name() << ": " << src.c_str() << LL_ENDL; //LL_INFOS() << name() << ": " << src.c_str() << LL_ENDL;
const size_t min_size = llmin(SIZE, src.size()); const size_t min_size = llmin(SIZE, src.size());
memcpy(buffer.data(), src.data(), min_size); memcpy(buffer.data(), src.data(), min_size);
buffer.data()[SIZE - 1] = '\0'; buffer.data()[SIZE - 1] = '\0';
@@ -243,18 +243,27 @@ struct crashpad_annotation : public crashpad::Annotation {
} }
}; };
#define DEFINE_CRASHPAD_ANNOTATION(name, len) \ #define DEFINE_CRASHPAD_ANNOTATION(name, len) \
static crashpad_annotation<len> g_crashpad_annotation_##name##_buffer(#name); static crashpad_annotation<len> g_crashpad_annotation_##name##_buffer("sentry[tags]["#name"]");
#define DEFINE_CRASHPAD_ANNOTATION_EXTRA(name, len) \
static crashpad_annotation<len> g_crashpad_annotation_##name##_buffer("sentry[extra]["#name"]");
#define SET_CRASHPAD_ANNOTATION_VALUE(name, value) \ #define SET_CRASHPAD_ANNOTATION_VALUE(name, value) \
g_crashpad_annotation_##name##_buffer.set(value); g_crashpad_annotation_##name##_buffer.set(value);
#else #else
#define SET_CRASHPAD_ANNOTATION_VALUE(name, value) #define SET_CRASHPAD_ANNOTATION_VALUE(name, value)
#define DEFINE_CRASHPAD_ANNOTATION_EXTRA(name, len)
#define DEFINE_CRASHPAD_ANNOTATION(name, len) #define DEFINE_CRASHPAD_ANNOTATION(name, len)
#endif #endif
DEFINE_CRASHPAD_ANNOTATION(fatal_message, 512); DEFINE_CRASHPAD_ANNOTATION_EXTRA(fatal_message, 512);
DEFINE_CRASHPAD_ANNOTATION(grid_name, 64); DEFINE_CRASHPAD_ANNOTATION(grid_name, 64);
DEFINE_CRASHPAD_ANNOTATION(cpu_string, 128); DEFINE_CRASHPAD_ANNOTATION(region_name, 64);
DEFINE_CRASHPAD_ANNOTATION(startup_state, 32); DEFINE_CRASHPAD_ANNOTATION_EXTRA(cpu_string, 128);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(gpu_string, 128);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(gl_version, 128);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(session_duration, 32);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(startup_state, 32);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(memory_sys, 32);
DEFINE_CRASHPAD_ANNOTATION_EXTRA(memory_alloc, 32);
////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor ////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
// //
@@ -1076,6 +1085,8 @@ bool LLAppViewer::init()
gGLManager.getGLInfo(gDebugInfo); gGLManager.getGLInfo(gDebugInfo);
gGLManager.printGLInfoString(); gGLManager.printGLInfoString();
writeDebugInfo();
// Load Default bindings // Load Default bindings
load_default_bindings(gSavedSettings.getBOOL("LiruUseZQSDKeys")); load_default_bindings(gSavedSettings.getBOOL("LiruUseZQSDKeys"));
@@ -1163,6 +1174,8 @@ bool LLAppViewer::init()
// save the graphics card // save the graphics card
gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString(); gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
writeDebugInfo();
// Save the current version to the prefs file // Save the current version to the prefs file
gSavedSettings.setString("LastRunVersion", gSavedSettings.setString("LastRunVersion",
LLVersionInfo::getChannelAndVersion()); LLVersionInfo::getChannelAndVersion());
@@ -1180,6 +1193,8 @@ bool LLAppViewer::init()
gGLActive = FALSE; gGLActive = FALSE;
LLViewerMedia::initClass(); LLViewerMedia::initClass();
LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ; LL_INFOS("InitInfo") << "Viewer media initialized." << LL_ENDL ;
writeDebugInfo();
return true; return true;
} }
@@ -1331,6 +1346,12 @@ bool LLAppViewer::mainLoop()
//clear call stack records //clear call stack records
LL_CLEAR_CALLSTACKS(); LL_CLEAR_CALLSTACKS();
#ifdef USE_CRASHPAD
// Not event based. Update per frame
SET_CRASHPAD_ANNOTATION_VALUE(session_duration, std::to_string(LLFrameTimer::getElapsedSeconds()));
SET_CRASHPAD_ANNOTATION_VALUE(memory_alloc, std::to_string((LLMemory::getCurrentRSS() >> 10)/1000.f));
#endif
//check memory availability information //check memory availability information
checkMemory() ; checkMemory() ;
@@ -2784,7 +2805,13 @@ void LLAppViewer::writeDebugInfo(bool isStatic)
#else #else
SET_CRASHPAD_ANNOTATION_VALUE(fatal_message, gDebugInfo["FatalMessage"].asString()); SET_CRASHPAD_ANNOTATION_VALUE(fatal_message, gDebugInfo["FatalMessage"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(grid_name, gDebugInfo["GridName"].asString()); SET_CRASHPAD_ANNOTATION_VALUE(grid_name, gDebugInfo["GridName"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(region_name, gDebugInfo["CurrentRegion"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(cpu_string, gDebugInfo["CPUInfo"]["CPUString"].asString()); SET_CRASHPAD_ANNOTATION_VALUE(cpu_string, gDebugInfo["CPUInfo"]["CPUString"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(gpu_string, gDebugInfo["GraphicsCard"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(gl_version, gDebugInfo["GLInfo"]["GLVersion"].asString());
SET_CRASHPAD_ANNOTATION_VALUE(session_duration, std::to_string(LLFrameTimer::getElapsedSeconds()));
SET_CRASHPAD_ANNOTATION_VALUE(memory_alloc, std::to_string((LLMemory::getCurrentRSS() >> 10) / 1000.f));
SET_CRASHPAD_ANNOTATION_VALUE(memory_sys, std::to_string(gDebugInfo["RAMInfo"]["Physical"].asInteger() * 0.001f));
#endif #endif
} }
@@ -2969,8 +2996,8 @@ void LLAppViewer::handleViewerCrash()
gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName(); gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds()); gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10; gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin(); gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
@@ -4832,11 +4859,14 @@ void LLAppViewer::disconnectViewer()
// floater_sound_preview.xml // floater_sound_preview.xml
// floater_animation_preview.xml // floater_animation_preview.xml
// files. // files.
// A more generic mechanism would be nice..
LLFloater* fl = static_cast<LLFloater*>(*it); LLFloater* fl = static_cast<LLFloater*>(*it);
if (fl if (fl
&& (fl->getName() == "Image Preview" && (fl->getName() == "Image Preview"
|| fl->getName() == "Sound Preview" || fl->getName() == "Sound Preview"
|| fl->getName() == "Animation Preview" || fl->getName() == "Animation Preview"
|| fl->getName() == "perm prefs"
)) ))
{ {
floaters_to_close.push_back(fl); floaters_to_close.push_back(fl);

View File

@@ -114,7 +114,7 @@ void LLFloaterObjectIMInfo::onClickMute()
// [/RLVa:KB] // [/RLVa:KB]
LLMuteList::instance().add(LLMute(mOwnerID, mName, mGroupOwned ? LLMute::GROUP : LLMute::AGENT)); LLMuteList::instance().add(LLMute(mOwnerID, mName, mGroupOwned ? LLMute::GROUP : LLMute::AGENT));
LLFloaterMute::showInstance(); LLFloaterMute::showInstance()->selectMute(mOwnerID);
close(); close();
} }

View File

@@ -42,6 +42,7 @@
#include "llviewerwindow.h" #include "llviewerwindow.h"
#include "lluictrlfactory.h" #include "lluictrlfactory.h"
#include "llpermissions.h" #include "llpermissions.h"
#include "llsdserialize.h"
#include "hippogridmanager.h" #include "hippogridmanager.h"
extern class AIHTTPTimeoutPolicy floaterPermsResponder_timeout; extern class AIHTTPTimeoutPolicy floaterPermsResponder_timeout;
@@ -63,6 +64,25 @@ U32 LLFloaterPerms::getEveryonePerms(std::string prefix)
return flags; return flags;
} }
//static
U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
{
U32 flags = PERM_MOVE;
if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
{
flags |= PERM_COPY;
}
if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
{
flags |= PERM_MODIFY;
}
if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
{
flags |= PERM_TRANSFER;
}
return flags;
}
//static //static
U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix) U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix)
{ {
@@ -83,25 +103,6 @@ U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix)
return flags; return flags;
} }
//static
U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
{
U32 flags = PERM_MOVE;
if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
{
flags |= PERM_COPY;
}
if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
{
flags |= PERM_MODIFY;
}
if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
{
flags |= PERM_TRANSFER;
}
return flags;
}
namespace namespace
{ {
void handle_checkboxes(LLView* view, const std::string& ctrl_name, const LLSD& value, const std::string& type) void handle_checkboxes(LLView* view, const std::string& ctrl_name, const LLSD& value, const std::string& type)
@@ -138,6 +139,7 @@ LLFloaterPermsDefault::LLFloaterPermsDefault(const LLSD& seed)
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml"); LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml");
} }
// String equivalents of enum Categories - initialization order must match enum order! // String equivalents of enum Categories - initialization order must match enum order!
const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] = const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
{ {
@@ -224,41 +226,66 @@ void LLFloaterPermsDefault::onClickCancel()
close(); close();
} }
class LLFloaterPermsResponder : public LLHTTPClient::ResponderWithResult struct LLFloaterPermsRequester final : LLSingleton<LLFloaterPermsRequester>
{
friend class LLSingleton<LLFloaterPermsRequester>;
std::string mUrl;
LLSD mReport;
U8 mRetriesCount = 0;
static void init(const std::string url, const LLSD report)
{
auto& inst = instance();
inst.mUrl = url;
inst.mReport = report;
inst.retry();
}
bool retry();
};
class LLFloaterPermsResponder final : public LLHTTPClient::ResponderWithResult
{ {
public:
LLFloaterPermsResponder() : LLHTTPClient::ResponderWithResult() {}
private:
static std::string sPreviousReason; static std::string sPreviousReason;
void httpFailure(void) void httpFailure() override
{ {
// <singu> Prevent 404s from annoying the user all the tme auto* requester = LLFloaterPermsRequester::getIfExists();
if (mStatus == HTTP_NOT_FOUND) if (!requester || requester->retry()) return;
LL_INFOS("FloaterPermsResponder") << "Failed to send default permissions to simulator. 404, reason: " << mReason << LL_ENDL;
else LLFloaterPermsRequester::deleteSingleton();
// </singu> const std::string& reason = getReason();
// Do not display the same error more than once in a row // Do not display the same error more than once in a row
if (mReason != sPreviousReason) if (reason != sPreviousReason)
{ {
sPreviousReason = mReason; sPreviousReason = reason;
LLSD args; LLSD args;
args["REASON"] = mReason; args["REASON"] = reason;
LLNotificationsUtil::add("DefaultObjectPermissions", args); LLNotificationsUtil::add("DefaultObjectPermissions", args);
} }
} }
void httpSuccess(void) void httpSuccess() override
{ {
//const LLSD& content = getContent();
//dump_sequential_xml("perms_responder_result.xml", content);
// Since we have had a successful POST call be sure to display the next error message // Since we have had a successful POST call be sure to display the next error message
// even if it is the same as a previous one. // even if it is the same as a previous one.
sPreviousReason = ""; sPreviousReason = "";
mCapSent = true; LL_INFOS("ObjectPermissionsFloater") << "Default permissions successfully sent to simulator" << LL_ENDL;
LL_INFOS("FloaterPermsResponder") << "Sent default permissions to simulator" << LL_ENDL;
} }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy() const { return floaterPermsResponder_timeout; } AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy() const override { return floaterPermsResponder_timeout; }
/*virtual*/ char const* getName() const { return "LLFloaterPermsResponder"; } char const* getName() const override { return "LLFloaterPermsResponder"; }
}; };
bool LLFloaterPermsRequester::retry()
{
if (++mRetriesCount < 5)
{
LLHTTPClient::post(mUrl, mReport, new LLFloaterPermsResponder);
return true;
}
return false;
}
std::string LLFloaterPermsResponder::sPreviousReason; std::string LLFloaterPermsResponder::sPreviousReason;
void LLFloaterPermsDefault::sendInitialPerms() void LLFloaterPermsDefault::sendInitialPerms()
@@ -266,12 +293,13 @@ void LLFloaterPermsDefault::sendInitialPerms()
if (!mCapSent) if (!mCapSent)
{ {
updateCap(); updateCap();
mCapSent = true;
} }
} }
void LLFloaterPermsDefault::updateCap() void LLFloaterPermsDefault::updateCap()
{ {
std::string object_url = gAgent.getRegion()->getCapability("AgentPreferences"); std::string object_url = gAgent.getRegionCapability("AgentPreferences");
if (!object_url.empty()) if (!object_url.empty())
{ {
@@ -283,13 +311,24 @@ void LLFloaterPermsDefault::updateCap()
report["default_object_perm_masks"]["NextOwner"] = report["default_object_perm_masks"]["NextOwner"] =
(LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]); (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]);
LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder()); {
std::ostringstream sent_perms_log;
LLSDSerialize::toPrettyXML(report, sent_perms_log);
LL_DEBUGS("ObjectPermissionsFloater") << "Sending default permissions to '"
<< object_url << "'\n"
<< sent_perms_log.str() << LL_ENDL;
}
LLFloaterPermsRequester::init(object_url, report);
} }
else
{
LL_DEBUGS("ObjectPermissionsFloater") << "AgentPreferences cap not available." << LL_ENDL;
}
} }
void LLFloaterPermsDefault::ok() void LLFloaterPermsDefault::ok()
{ {
// Changes were already applied to saved settings. // Changes were already applied automatically to saved settings.
// Refreshing internal values makes it official. // Refreshing internal values makes it official.
refresh(); refresh();
@@ -302,11 +341,11 @@ void LLFloaterPermsDefault::cancel()
{ {
for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++) for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++)
{ {
gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerCopy", mNextOwnerCopy[iter]); gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerCopy", mNextOwnerCopy[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerModify", mNextOwnerModify[iter]); gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerModify", mNextOwnerModify[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerTransfer", mNextOwnerTransfer[iter]); gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerTransfer", mNextOwnerTransfer[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]);
gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]);
gSavedPerAccountSettings.setBOOL(sCategoryNames[iter]+"EveryoneExport", mEveryoneExport[iter]); gSavedPerAccountSettings.setBOOL(sCategoryNames[iter]+"EveryoneExport", mEveryoneExport[iter]);
} }
} }

View File

@@ -2010,7 +2010,7 @@ void LLFolderView::scrollToShowSelection()
// However we allow scrolling for folder views with mAutoSelectOverride // However we allow scrolling for folder views with mAutoSelectOverride
// (used in Places SP) as an exception because the selection in them // (used in Places SP) as an exception because the selection in them
// is not reset during items filtering. See STORM-133. // is not reset during items filtering. See STORM-133.
if ( (!LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mAutoSelectOverride) if ( (LLInventoryModelBackgroundFetch::instance().isEverythingFetched() || mAutoSelectOverride)
&& mSelectedItems.size() ) && mSelectedItems.size() )
{ {
mNeedsScroll = TRUE; mNeedsScroll = TRUE;

View File

@@ -801,7 +801,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol
// Now we're adding the actual line of text, so erase the // Now we're adding the actual line of text, so erase the
// "Foo is typing..." text segment, and the optional timestamp // "Foo is typing..." text segment, and the optional timestamp
// if it was present. JC // if it was present. JC
removeTypingIndicator(NULL); removeTypingIndicator(source);
// Actually add the line // Actually add the line
bool prepend_newline = true; bool prepend_newline = true;
@@ -1458,7 +1458,7 @@ void LLFloaterIMPanel::onSendMsg()
bool other_was_typing = mOtherTyping; bool other_was_typing = mOtherTyping;
addHistoryLine(utf8_text, gSavedSettings.getColor("UserChatColor"), true, gAgentID, name); addHistoryLine(utf8_text, gSavedSettings.getColor("UserChatColor"), true, gAgentID, name);
if (other_was_typing) addTypingIndicator(mOtherTypingName); if (other_was_typing) addTypingIndicator(mOtherParticipantUUID);
} }
} }
else else
@@ -1588,53 +1588,84 @@ void LLFloaterIMPanel::sendTypingState(bool typing)
} }
void LLFloaterIMPanel::processIMTyping(const LLIMInfo* im_info, bool typing) void LLFloaterIMPanel::processIMTyping(const LLUUID& from_id, BOOL typing)
{ {
if (typing) if (typing)
{ {
// other user started typing // other user started typing
std::string name; addTypingIndicator(from_id);
if (!LLAvatarNameCache::getNSName(im_info->mFromID, name)) name = im_info->mName;
addTypingIndicator(name);
} }
else else
{ {
// other user stopped typing // other user stopped typing
removeTypingIndicator(im_info); removeTypingIndicator(from_id);
} }
} }
void LLFloaterIMPanel::addTypingIndicator(const std::string &name) void LLFloaterIMPanel::addTypingIndicator(const LLUUID& from_id)
{ {
// we may have lost a "stop-typing" packet, don't add it twice // Singu TODO: Actually implement this?
if (!mOtherTyping) /* Operation of "<name> is typing" state machine:
Not Typing state:
User types in P2P IM chat ... Send Start Typing, save Started time,
start Idle Timer (N seconds) go to Typing state
Typing State:
User enters a non-return character: if Now - Started > ME_TYPING_TIMEOUT, send
Start Typing, restart Idle Timer
User enters a return character: stop Idle Timer, send IM and Stop
Typing, go to Not Typing state
Idle Timer expires: send Stop Typing, go to Not Typing state
The recipient has a complementary state machine in which a Start Typing
that is not followed by either an IM or another Start Typing within OTHER_TYPING_TIMEOUT
seconds switches the sender out of typing state.
This has the nice quality of being self-healing for lost start/stop
messages while adding messages only for the (relatively rare) case of a
user who types a very long message (one that takes more than ME_TYPING_TIMEOUT seconds
to type).
Note: OTHER_TYPING_TIMEOUT must be > ME_TYPING_TIMEOUT for proper operation of the state machine
*/
// We may have lost a "stop-typing" packet, don't add it twice
if (from_id.notNull() && !mOtherTyping)
{ {
mOtherTyping = true;
// Save im_info so that removeTypingIndicator can be properly called because a timeout has occurred
LLAvatarNameCache::getNSName(from_id, mOtherTypingName);
mTypingLineStartIndex = mHistoryEditor->getWText().length(); mTypingLineStartIndex = mHistoryEditor->getWText().length();
LLUIString typing_start = sTypingStartString; LLUIString typing_start = sTypingStartString;
typing_start.setArg("[NAME]", name); typing_start.setArg("[NAME]", mOtherTypingName);
addHistoryLine(typing_start, gSavedSettings.getColor4("SystemChatColor"), false); addHistoryLine(typing_start, gSavedSettings.getColor4("SystemChatColor"), false);
mOtherTypingName = name;
mOtherTyping = true; // Update speaker
LLIMSpeakerMgr* speaker_mgr = mSpeakers;
if ( speaker_mgr )
{
speaker_mgr->setSpeakerTyping(from_id, TRUE);
}
} }
// MBW -- XXX -- merge from release broke this (argument to this function changed from an LLIMInfo to a name)
// Richard will fix.
// mSpeakers->setSpeakerTyping(im_info->mFromID, TRUE);
} }
void LLFloaterIMPanel::removeTypingIndicator(const LLUUID& from_id)
void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
{ {
if (mOtherTyping) if (mOtherTyping)
{ {
// Must do this first, otherwise addHistoryLine calls us again.
mOtherTyping = false; mOtherTyping = false;
S32 chars_to_remove = mHistoryEditor->getWText().length() - mTypingLineStartIndex; S32 chars_to_remove = mHistoryEditor->getWText().length() - mTypingLineStartIndex;
mHistoryEditor->removeTextFromEnd(chars_to_remove); mHistoryEditor->removeTextFromEnd(chars_to_remove);
if (im_info)
if (from_id.notNull())
{ {
mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE); mSpeakers->setSpeakerTyping(from_id, FALSE);
} }
} }
} }

View File

@@ -39,7 +39,6 @@
class LLAvatarName; class LLAvatarName;
class LLIMSpeakerMgr; class LLIMSpeakerMgr;
class LLIMInfo;
class LLInventoryCategory; class LLInventoryCategory;
class LLInventoryItem; class LLInventoryItem;
class LLLineEditor; class LLLineEditor;
@@ -126,7 +125,7 @@ public:
void sessionInitReplyReceived(const LLUUID& im_session_id); void sessionInitReplyReceived(const LLUUID& im_session_id);
// Handle other participant in the session typing. // Handle other participant in the session typing.
void processIMTyping(const LLIMInfo* im_info, bool typing); void processIMTyping(const LLUUID& from_id, BOOL typing);
static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata); static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata);
//show error statuses to the user //show error statuses to the user
@@ -177,10 +176,10 @@ private:
void setTyping(bool typing); void setTyping(bool typing);
// Add the "User is typing..." indicator. // Add the "User is typing..." indicator.
void addTypingIndicator(const std::string &name); void addTypingIndicator(const LLUUID& from_id);
// Remove the "User is typing..." indicator. // Remove the "User is typing..." indicator.
void removeTypingIndicator(const LLIMInfo* im_info); void removeTypingIndicator(const LLUUID& from_id = LLUUID::null);
void sendTypingState(bool typing); void sendTypingState(bool typing);

View File

@@ -641,8 +641,7 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
{ {
RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(), session_id); RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(), session_id);
// We won't receive a typing stop message, so do that manually (see comment at the end of LLFloaterIMPanel::sendMsg) // We won't receive a typing stop message, so do that manually (see comment at the end of LLFloaterIMPanel::sendMsg)
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem); gIMMgr->processIMTypingStop(from_id, dialog);
gIMMgr->processIMTypingStop(im_info);
} }
// [/RLVa:KB] // [/RLVa:KB]
else if (offline == IM_ONLINE else if (offline == IM_ONLINE
@@ -918,16 +917,15 @@ void LLIMProcessing::processNewMessage(const LLUUID& from_id,
autoresponder_finish(show_autoresponded, session_id, from_id, name, itemid, is_muted); autoresponder_finish(show_autoresponded, session_id, from_id, name, itemid, is_muted);
} }
} }
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem);
gIMMgr->processIMTypingStart(im_info); gIMMgr->processIMTypingStart(from_id, dialog);
script_msg_api(from_id.asString() + ", 4"); script_msg_api(from_id.asString() + ", 4");
} }
break; break;
case IM_TYPING_STOP: case IM_TYPING_STOP:
{ {
LLPointer<LLIMInfo> im_info = new LLIMInfo(gMessageSystem); gIMMgr->processIMTypingStop(from_id, dialog);
gIMMgr->processIMTypingStop(im_info);
script_msg_api(from_id.asString() + ", 5"); script_msg_api(from_id.asString() + ", 5");
} }
break; break;

View File

@@ -1138,23 +1138,23 @@ void LLIMMgr::noteMutedUsers(LLFloaterIMPanel* floater,
} }
} }
void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info) void LLIMMgr::processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type)
{ {
processIMTypingCore(im_info, TRUE); processIMTypingCore(from_id, im_type, TRUE);
} }
void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info) void LLIMMgr::processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type)
{ {
processIMTypingCore(im_info, FALSE); processIMTypingCore(from_id, im_type, FALSE);
} }
void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing) void LLIMMgr::processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing)
{ {
LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID); LLUUID session_id = computeSessionID(im_type, from_id);
LLFloaterIMPanel* floater = findFloaterBySession(session_id); LLFloaterIMPanel* im_floater = findFloaterBySession(session_id);
if (floater) if (im_floater)
{ {
floater->processIMTyping(im_info, typing); im_floater->processIMTyping(from_id, typing);
} }
} }
@@ -1275,10 +1275,10 @@ LLFloaterChatterBox* LLIMMgr::getFloater()
return LLFloaterChatterBox::getInstance(LLSD()); return LLFloaterChatterBox::getInstance(LLSD());
} }
class LLViewerChatterBoxSessionStartReply : public LLHTTPNode class LLViewerChatterBoxSessionStartReply final : public LLHTTPNode
{ {
public: public:
virtual void describe(Description& desc) const void describe(Description& desc) const override
{ {
desc.shortInfo("Used for receiving a reply to a request to initialize an ChatterBox session"); desc.shortInfo("Used for receiving a reply to a request to initialize an ChatterBox session");
desc.postAPI(); desc.postAPI();
@@ -1287,18 +1287,15 @@ public:
desc.source(__FILE__, __LINE__); desc.source(__FILE__, __LINE__);
} }
virtual void post(ResponsePtr response, void post(ResponsePtr response,
const LLSD& context, const LLSD& context,
const LLSD& input) const const LLSD& input) const override
{ {
LLSD body;
LLUUID temp_session_id;
LLUUID session_id; LLUUID session_id;
bool success;
body = input["body"]; LLSD body = input["body"];
success = body["success"].asBoolean(); bool success = body["success"].asBoolean();
temp_session_id = body["temp_session_id"].asUUID(); LLUUID temp_session_id = body["temp_session_id"].asUUID();
if ( success ) if ( success )
{ {
@@ -1336,10 +1333,10 @@ public:
} }
}; };
class LLViewerChatterBoxSessionEventReply : public LLHTTPNode class LLViewerChatterBoxSessionEventReply final : public LLHTTPNode
{ {
public: public:
virtual void describe(Description& desc) const void describe(Description& desc) const override
{ {
desc.shortInfo("Used for receiving a reply to a ChatterBox session event"); desc.shortInfo("Used for receiving a reply to a ChatterBox session event");
desc.postAPI(); desc.postAPI();
@@ -1348,24 +1345,18 @@ public:
desc.source(__FILE__, __LINE__); desc.source(__FILE__, __LINE__);
} }
virtual void post(ResponsePtr response, void post(ResponsePtr response,
const LLSD& context, const LLSD& context,
const LLSD& input) const const LLSD& input) const override
{ {
LLUUID session_id;
bool success;
LLSD body = input["body"]; LLSD body = input["body"];
success = body["success"].asBoolean(); bool success = body["success"].asBoolean();
session_id = body["session_id"].asUUID(); LLUUID session_id = body["session_id"].asUUID();
if ( !success ) if ( !success )
{ {
//throw an error dialog //throw an error dialog
LLFloaterIMPanel* floater = if (auto* floater = gIMMgr->findFloaterBySession(session_id))
gIMMgr->findFloaterBySession(session_id);
if (floater)
{ {
floater->showSessionEventError( floater->showSessionEventError(
body["event"].asString(), body["event"].asString(),
@@ -1378,46 +1369,40 @@ public:
class LLViewerForceCloseChatterBoxSession: public LLHTTPNode class LLViewerForceCloseChatterBoxSession: public LLHTTPNode
{ {
public: public:
virtual void post(ResponsePtr response, void post(ResponsePtr response,
const LLSD& context, const LLSD& context,
const LLSD& input) const const LLSD& input) const override
{ {
LLUUID session_id; LLUUID session_id = input["body"]["session_id"].asUUID();
std::string reason; std::string reason = input["body"]["reason"].asString();
session_id = input["body"]["session_id"].asUUID(); if (auto* floater = gIMMgr ->findFloaterBySession(session_id))
reason = input["body"]["reason"].asString();
LLFloaterIMPanel* floater =
gIMMgr ->findFloaterBySession(session_id);
if ( floater )
{ {
floater->showSessionForceClose(reason); floater->showSessionForceClose(reason);
} }
} }
}; };
class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode class LLViewerChatterBoxSessionAgentListUpdates final : public LLHTTPNode
{ {
public: public:
virtual void post( void post(
ResponsePtr responder, ResponsePtr responder,
const LLSD& context, const LLSD& context,
const LLSD& input) const const LLSD& input) const override
{ {
const LLUUID& session_id = input["body"]["session_id"].asUUID(); const LLUUID& session_id = input["body"]["session_id"].asUUID();
gIMMgr->processAgentListUpdates(session_id, input["body"]); gIMMgr->processAgentListUpdates(session_id, input["body"]);
} }
}; };
class LLViewerChatterBoxSessionUpdate : public LLHTTPNode class LLViewerChatterBoxSessionUpdate final : public LLHTTPNode
{ {
public: public:
virtual void post( void post(
ResponsePtr responder, ResponsePtr responder,
const LLSD& context, const LLSD& context,
const LLSD& input) const const LLSD& input) const override
{ {
LLUUID session_id = input["body"]["session_id"].asUUID(); LLUUID session_id = input["body"]["session_id"].asUUID();
LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id); LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id);
@@ -1445,14 +1430,14 @@ void leave_group_chat(const LLUUID& from_id, const LLUUID& session_id)
gIMMgr->removeSession(session_id); gIMMgr->removeSession(session_id);
} }
class LLViewerChatterBoxInvitation : public LLHTTPNode class LLViewerChatterBoxInvitation final : public LLHTTPNode
{ {
public: public:
virtual void post( void post(
ResponsePtr response, ResponsePtr response,
const LLSD& context, const LLSD& context,
const LLSD& input) const const LLSD& input) const override
{ {
//for backwards compatiblity reasons...we need to still //for backwards compatiblity reasons...we need to still
//check for 'text' or 'voice' invitations...bleh //check for 'text' or 'voice' invitations...bleh
@@ -1582,10 +1567,9 @@ public:
LLFloaterChat::addChat(chat, TRUE, is_this_agent); LLFloaterChat::addChat(chat, TRUE, is_this_agent);
//K now we want to accept the invitation //K now we want to accept the invitation
std::string url = gAgent.getRegion()->getCapability( std::string url = gAgent.getRegionCapability("ChatSessionRequest");
"ChatSessionRequest");
if ( url != "" ) if (!url.empty())
{ {
LLSD data; LLSD data;
data["method"] = "accept invitation"; data["method"] = "accept invitation";

View File

@@ -42,7 +42,7 @@
class LLFloaterChatterBox; class LLFloaterChatterBox;
class LLFloaterIMPanel; class LLFloaterIMPanel;
class LLIMMgr : public LLSingleton<LLIMMgr> class LLIMMgr final : public LLSingleton<LLIMMgr>
{ {
public: public:
enum EInvitationType enum EInvitationType
@@ -121,8 +121,8 @@ public:
void updateFloaterSessionID(const LLUUID& old_session_id, void updateFloaterSessionID(const LLUUID& old_session_id,
const LLUUID& new_session_id); const LLUUID& new_session_id);
void processIMTypingStart(const LLIMInfo* im_info); void processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type);
void processIMTypingStop(const LLIMInfo* im_info); void processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type);
void clearNewIMNotification(); void clearNewIMNotification();
@@ -209,7 +209,7 @@ private:
void noteOfflineUsers(LLFloaterIMPanel* panel, const uuid_vec_t& ids); void noteOfflineUsers(LLFloaterIMPanel* panel, const uuid_vec_t& ids);
void noteMutedUsers(LLFloaterIMPanel* panel, const uuid_vec_t& ids); void noteMutedUsers(LLFloaterIMPanel* panel, const uuid_vec_t& ids);
void processIMTypingCore(const LLIMInfo* im_info, BOOL typing); void processIMTypingCore(const LLUUID& from_id, const EInstantMessage im_type, BOOL typing);
private: private:
std::set<LLHandle<LLFloater> > mFloaters; std::set<LLHandle<LLFloater> > mFloaters;

View File

@@ -72,7 +72,7 @@ namespace
{ {
// This method is used to return an object to mute given an object id. // This method is used to return an object to mute given an object id.
// Its used by the LLMute constructor and LLMuteList::isMuted. // Its used by the LLMute constructor and LLMuteList::isMuted.
LLViewerObject* get_object_to_mute_from_id(LLUUID object_id) LLViewerObject* get_object_to_mute_from_id(const LLUUID& object_id)
{ {
LLViewerObject *objectp = gObjectList.findObject(object_id); LLViewerObject *objectp = gObjectList.findObject(object_id);
if ((objectp) && (!objectp->isAvatar())) if ((objectp) && (!objectp->isAvatar()))
@@ -91,11 +91,11 @@ namespace
class LLDispatchEmptyMuteList : public LLDispatchHandler class LLDispatchEmptyMuteList : public LLDispatchHandler
{ {
public: public:
virtual bool operator()( bool operator()(
const LLDispatcher* dispatcher, const LLDispatcher* dispatcher,
const std::string& key, const std::string& key,
const LLUUID& invoice, const LLUUID& invoice,
const sparam_t& strings) const sparam_t& strings) override
{ {
LLMuteList::getInstance()->setLoaded(); LLMuteList::getInstance()->setLoaded();
return true; return true;
@@ -160,10 +160,10 @@ std::string LLMute::getDisplayType() const
LLMuteList* LLMuteList::getInstance() LLMuteList* LLMuteList::getInstance()
{ {
// Register callbacks at the first time that we find that the message system has been created. // Register callbacks at the first time that we find that the message system has been created.
static BOOL registered = FALSE; static bool registered = false;
if( !registered && gMessageSystem != NULL) if( !registered && gMessageSystem)
{ {
registered = TRUE; registered = true;
// Register our various callbacks // Register our various callbacks
gMessageSystem->setHandlerFuncFast(_PREHASH_MuteListUpdate, processMuteListUpdate); gMessageSystem->setHandlerFuncFast(_PREHASH_MuteListUpdate, processMuteListUpdate);
gMessageSystem->setHandlerFuncFast(_PREHASH_UseCachedMuteList, processUseCachedMuteList); gMessageSystem->setHandlerFuncFast(_PREHASH_UseCachedMuteList, processUseCachedMuteList);
@@ -206,7 +206,7 @@ BOOL LLMuteList::isLinden(const std::string& name) const
tokenizer::iterator token_iter = tokens.begin(); tokenizer::iterator token_iter = tokens.begin();
if (token_iter == tokens.end()) return FALSE; if (token_iter == tokens.end()) return FALSE;
token_iter++; ++token_iter;
if (token_iter == tokens.end()) return FALSE; if (token_iter == tokens.end()) return FALSE;
std::string last_name = *token_iter; std::string last_name = *token_iter;
@@ -227,7 +227,7 @@ static LLVOAvatar* find_avatar(const LLUUID& id)
} }
else else
{ {
return NULL; return nullptr;
} }
} }
@@ -237,6 +237,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
if ((mute.mType == LLMute::AGENT) if ((mute.mType == LLMute::AGENT)
&& isLinden(mute.mName) && (flags & LLMute::flagTextChat || flags == 0)) && isLinden(mute.mName) && (flags & LLMute::flagTextChat || flags == 0))
{ {
LL_WARNS() << "Trying to mute a Linden; ignored" << LL_ENDL;
LLNotifications::instance().add("MuteLinden", LLSD(), LLSD()); LLNotifications::instance().add("MuteLinden", LLSD(), LLSD());
return FALSE; return FALSE;
} }
@@ -245,6 +246,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
if (mute.mType == LLMute::AGENT if (mute.mType == LLMute::AGENT
&& mute.mID == gAgent.getID()) && mute.mID == gAgent.getID())
{ {
LL_WARNS() << "Trying to self; ignored" << LL_ENDL;
return FALSE; return FALSE;
} }
@@ -275,67 +277,67 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
} }
else else
{ {
LL_INFOS() << "duplicate mute ignored" << LL_ENDL;
// was duplicate // was duplicate
return FALSE; return FALSE;
} }
} }
// Need a local (non-const) copy to set up flags properly.
LLMute localmute = mute;
// If an entry for the same entity is already in the list, remove it, saving flags as necessary.
mute_set_t::iterator it = mMutes.find(localmute);
bool duplicate = it != mMutes.end();
if (duplicate)
{
// This mute is already in the list. Save the existing entry's flags if that's warranted.
localmute.mFlags = it->mFlags;
mMutes.erase(it);
// Don't need to call notifyObservers() here, since it will happen after the entry has been re-added below.
}
else else
{ {
// Need a local (non-const) copy to set up flags properly. // There was no entry in the list previously. Fake things up by making it look like the previous entry had all properties unmuted.
LLMute localmute = mute; localmute.mFlags = LLMute::flagAll;
}
// If an entry for the same entity is already in the list, remove it, saving flags as necessary. if(flags)
mute_set_t::iterator it = mMutes.find(localmute); {
if (it != mMutes.end()) // The user passed some combination of flags. Make sure those flag bits are turned off (i.e. those properties will be muted).
{ localmute.mFlags &= (~flags);
// This mute is already in the list. Save the existing entry's flags if that's warranted. }
localmute.mFlags = it->mFlags; else
{
// The user passed 0. Make sure all flag bits are turned off (i.e. all properties will be muted).
localmute.mFlags = 0;
}
mMutes.erase(it); // (re)add the mute entry.
// Don't need to call notifyObservers() here, since it will happen after the entry has been re-added below. {
} auto result = mMutes.insert(localmute);
else if (result.second)
{ {
// There was no entry in the list previously. Fake things up by making it look like the previous entry had all properties unmuted. LL_INFOS() << "Muting " << localmute.mName << " id " << localmute.mID << " flags " << localmute.mFlags << LL_ENDL;
localmute.mFlags = LLMute::flagAll; updateAdd(localmute);
} notifyObservers();
notifyObserversDetailed(localmute);
if(flags) if(!(localmute.mFlags & LLMute::flagParticles))
{
// The user passed some combination of flags. Make sure those flag bits are turned off (i.e. those properties will be muted).
localmute.mFlags &= (~flags);
}
else
{
// The user passed 0. Make sure all flag bits are turned off (i.e. all properties will be muted).
localmute.mFlags = 0;
}
// (re)add the mute entry.
{
std::pair<mute_set_t::iterator, bool> result = mMutes.insert(localmute);
if (result.second)
{ {
LL_INFOS() << "Muting " << localmute.mName << " id " << localmute.mID << " flags " << localmute.mFlags << LL_ENDL; //Kill all particle systems owned by muted task
updateAdd(localmute); if(localmute.mType == LLMute::AGENT || localmute.mType == LLMute::OBJECT)
notifyObservers();
notifyObserversDetailed(localmute);
if(!(localmute.mFlags & LLMute::flagParticles))
{ {
//Kill all particle systems owned by muted task LLViewerPartSim::getInstance()->clearParticlesByOwnerID(localmute.mID);
if(localmute.mType == LLMute::AGENT || localmute.mType == LLMute::OBJECT)
{
LLViewerPartSim::getInstance()->clearParticlesByOwnerID(localmute.mID);
}
} }
//mute local lights that are attached to the avatar
LLVOAvatar *avatarp = find_avatar(localmute.mID);
if (avatarp)
{
LLPipeline::removeMutedAVsLights(avatarp);
}
return TRUE;
} }
//mute local lights that are attached to the avatar
LLVOAvatar *avatarp = find_avatar(localmute.mID);
if (avatarp)
{
LLPipeline::removeMutedAVsLights(avatarp);
}
return !duplicate;
} }
} }
@@ -514,18 +516,14 @@ std::vector<LLMute> LLMuteList::getMutes() const
{ {
std::vector<LLMute> mutes; std::vector<LLMute> mutes;
for (mute_set_t::const_iterator it = mMutes.begin(); for (const auto& mMute : mMutes)
it != mMutes.end();
++it)
{ {
mutes.push_back(*it); mutes.push_back(mMute);
} }
for (string_set_t::const_iterator it = mLegacyMutes.begin(); for (const auto& mLegacyMute : mLegacyMutes)
it != mLegacyMutes.end();
++it)
{ {
LLMute legacy(LLUUID::null, *it); LLMute legacy(LLUUID::null, mLegacyMute);
mutes.push_back(legacy); mutes.push_back(legacy);
} }
@@ -538,7 +536,7 @@ std::vector<LLMute> LLMuteList::getMutes() const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
BOOL LLMuteList::loadFromFile(const std::string& filename) BOOL LLMuteList::loadFromFile(const std::string& filename)
{ {
if(!filename.size()) if(filename.empty())
{ {
LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL; LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL;
return FALSE; return FALSE;
@@ -588,7 +586,7 @@ BOOL LLMuteList::loadFromFile(const std::string& filename)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
BOOL LLMuteList::saveToFile(const std::string& filename) BOOL LLMuteList::saveToFile(const std::string& filename)
{ {
if(!filename.size()) if(filename.empty())
{ {
LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL; LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL;
return FALSE; return FALSE;
@@ -603,23 +601,19 @@ BOOL LLMuteList::saveToFile(const std::string& filename)
// legacy mutes have null uuid // legacy mutes have null uuid
std::string id_string; std::string id_string;
LLUUID::null.toString(id_string); LLUUID::null.toString(id_string);
for (string_set_t::iterator it = mLegacyMutes.begin(); for (const auto& mLegacyMute : mLegacyMutes)
it != mLegacyMutes.end();
++it)
{ {
fprintf(fp, "%d %s %s|\n", (S32)LLMute::BY_NAME, id_string.c_str(), it->c_str()); fprintf(fp, "%d %s %s|\n", (S32)LLMute::BY_NAME, id_string.c_str(), mLegacyMute.c_str());
} }
for (mute_set_t::iterator it = mMutes.begin(); for (const auto& mMute : mMutes)
it != mMutes.end();
++it)
{ {
// Don't save external mutes as they are not sent to the server and probably won't // Don't save external mutes as they are not sent to the server and probably won't
//be valid next time anyway. //be valid next time anyway.
if (it->mType != LLMute::EXTERNAL) if (mMute.mType != LLMute::EXTERNAL)
{ {
it->mID.toString(id_string); mMute.mID.toString(id_string);
const std::string& name = it->mName; const std::string& name = mMute.mName;
fprintf(fp, "%d %s %s|%u\n", (S32)it->mType, id_string.c_str(), name.c_str(), it->mFlags); fprintf(fp, "%d %s %s|%u\n", (S32)mMute.mType, id_string.c_str(), name.c_str(), mMute.mFlags);
} }
} }
fclose(fp); fclose(fp);
@@ -629,6 +623,9 @@ BOOL LLMuteList::saveToFile(const std::string& filename)
BOOL LLMuteList::isMuted(const LLUUID& id, const std::string& name, U32 flags) const BOOL LLMuteList::isMuted(const LLUUID& id, const std::string& name, U32 flags) const
{ {
if (mMutes.empty() && mLegacyMutes.empty())
return FALSE;
// for objects, check for muting on their parent prim // for objects, check for muting on their parent prim
LLViewerObject* mute_object = get_object_to_mute_from_id(id); LLViewerObject* mute_object = get_object_to_mute_from_id(id);
LLUUID id_to_check = (mute_object) ? mute_object->getID() : id; LLUUID id_to_check = (mute_object) ? mute_object->getID() : id;
@@ -662,10 +659,8 @@ BOOL LLMuteList::isMuted(const LLUUID& id, const std::string& name, U32 flags) c
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void LLMuteList::requestFromServer(const LLUUID& agent_id) void LLMuteList::requestFromServer(const LLUUID& agent_id)
{ {
std::string agent_id_string; std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
std::string filename; llformat("%s.cached_mute", agent_id.asString().c_str()));
agent_id.toString(agent_id_string);
filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute";
LLCRC crc; LLCRC crc;
crc.update(filename); crc.update(filename);
@@ -688,10 +683,8 @@ void LLMuteList::cache(const LLUUID& agent_id)
// Write to disk even if empty. // Write to disk even if empty.
if(mIsLoaded) if(mIsLoaded)
{ {
std::string agent_id_string; std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
std::string filename; llformat("%s.cached_mute", agent_id.asString().c_str()));
agent_id.toString(agent_id_string);
filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute";
saveToFile(filename); saveToFile(filename);
} }
} }
@@ -729,10 +722,8 @@ void LLMuteList::processUseCachedMuteList(LLMessageSystem* msg, void**)
{ {
LL_INFOS() << "LLMuteList::processUseCachedMuteList()" << LL_ENDL; LL_INFOS() << "LLMuteList::processUseCachedMuteList()" << LL_ENDL;
std::string agent_id_string; std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
gAgent.getID().toString(agent_id_string); llformat("%s.cached_mute", gAgent.getID().asString().c_str()));
std::string filename;
filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute";
LLMuteList::getInstance()->loadFromFile(filename); LLMuteList::getInstance()->loadFromFile(filename);
} }

View File

@@ -985,7 +985,8 @@ void LLPanelAvatarPicks::processProperties(void* data, EAvatarProcessorType type
// are no tabs in the container. // are no tabs in the container.
tabs->selectFirstTab(); tabs->selectFirstTab();
bool edit(getPanelAvatar()->isEditable()); bool edit(getPanelAvatar()->isEditable());
bool can_add = self && tabs->getTabCount() < LLAgentBenefitsMgr::current().getPicksLimit(); auto count = tabs->getTabCount();
bool can_add = self && count < LLAgentBenefitsMgr::current().getPicksLimit();
LLView* view = getChildView("New..."); LLView* view = getChildView("New...");
view->setEnabled(can_add view->setEnabled(can_add
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
@@ -993,7 +994,7 @@ void LLPanelAvatarPicks::processProperties(void* data, EAvatarProcessorType type
// [/RLVa:KB] // [/RLVa:KB]
view->setVisible(self && edit); view->setVisible(self && edit);
view = getChildView("Delete..."); view = getChildView("Delete...");
view->setEnabled(can_add); view->setEnabled(count);
view->setVisible(self && edit); view->setVisible(self && edit);
//For pick import/export - RK //For pick import/export - RK
@@ -1001,7 +1002,7 @@ void LLPanelAvatarPicks::processProperties(void* data, EAvatarProcessorType type
view->setVisible(self && edit); view->setVisible(self && edit);
view->setEnabled(can_add); view->setEnabled(can_add);
view = getChildView("Export..."); view = getChildView("Export...");
view->setEnabled(can_add); view->setEnabled(count);
view->setVisible(self); view->setVisible(self);
childSetVisible("loading_text", false); childSetVisible("loading_text", false);

View File

@@ -493,21 +493,10 @@ void LLSurface::disconnectNeighbor(LLSurface* surfacep, U32 direction)
{ {
if (surfacep && surfacep == mNeighbors[direction]) if (surfacep && surfacep == mNeighbors[direction])
{ {
// Iterate through surface patches, removing any connectivity to removed surface. mNeighbors[direction] = NULL;
// Extra branches for debugging. for (auto& patchp : mPatchList)
if (!gHippoGridManager->getCurrentGrid()->isSecondLife())
{ {
for (auto& patchp : mPatchList) patchp->disconnectNeighbor(surfacep);
{
patchp->disconnectNeighbor(surfacep);
}
}
if (gHippoGridManager->getCurrentGrid()->isSecondLife())
{
for (auto& patchp : mPatchList)
{
patchp->disconnectNeighbor(surfacep);
}
} }
} }
} }
@@ -515,46 +504,13 @@ void LLSurface::disconnectNeighbor(LLSurface* surfacep, U32 direction)
void LLSurface::disconnectAllNeighbors() void LLSurface::disconnectAllNeighbors()
{ {
// Pulled out of loop to debug. for (size_t i = 0; i < mNeighbors.size(); ++i)
if (mNeighbors[EAST])
{ {
mNeighbors[EAST]->disconnectNeighbor(this, gDirOpposite[EAST]); auto& neighbor = mNeighbors[i];
} if (neighbor)
if (mNeighbors[NORTH])
{
mNeighbors[NORTH]->disconnectNeighbor(this, gDirOpposite[NORTH]);
}
if (mNeighbors[WEST])
{
mNeighbors[WEST]->disconnectNeighbor(this, gDirOpposite[WEST]);
}
if (mNeighbors[SOUTH])
{
mNeighbors[SOUTH]->disconnectNeighbor(this, gDirOpposite[SOUTH]);
}
if (mNeighbors[NORTHEAST])
{
mNeighbors[NORTHEAST]->disconnectNeighbor(this, gDirOpposite[NORTHEAST]);
}
if (mNeighbors[NORTHWEST])
{
mNeighbors[NORTHWEST]->disconnectNeighbor(this, gDirOpposite[NORTHWEST]);
}
if (mNeighbors[SOUTHWEST])
{
mNeighbors[SOUTHWEST]->disconnectNeighbor(this, gDirOpposite[SOUTHWEST]);
}
if (mNeighbors[SOUTHEAST])
{
mNeighbors[SOUTHEAST]->disconnectNeighbor(this, gDirOpposite[SOUTHEAST]);
}
S32 i;
for (i = 0; i < 8; i++)
{
if (mNeighbors[i])
{ {
//mNeighbors[i]->disconnectNeighbor(this); neighbor->disconnectNeighbor(this, gDirOpposite[i]);
mNeighbors[i] = NULL; neighbor = NULL;
} }
} }
} }

View File

@@ -167,7 +167,7 @@ public:
// +---+---+---+ // +---+---+---+
// |SW | S | SE| // |SW | S | SE|
// +---+---+---+ // +---+---+---+
LLSurface *mNeighbors[8]; // Adjacent patches std::array<LLSurface*, 8> mNeighbors; // Adjacent patches
U32 mType; // Useful for identifying derived classes U32 mType; // Useful for identifying derived classes

View File

@@ -872,7 +872,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mCacheReadCount(0U), mCacheReadCount(0U),
mCacheWriteCount(0U) mCacheWriteCount(0U)
{ {
mCanUseNET = mUrl.empty() ; mCanUseNET = mUrl.empty() && !gHippoGridManager->getConnectedGrid()->isSecondLife();
if (!mCanUseNET) if (!mCanUseNET)
{ {
@@ -1236,9 +1236,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == LOAD_FROM_NETWORK) if (mState == LOAD_FROM_NETWORK)
{ {
static LLCachedControl<bool> use_http(gSavedSettings,"ImagePipelineUseHTTP"); static LLCachedControl<bool> use_http(gSavedSettings,"ImagePipelineUseHTTP");
bool is_sl = gHippoGridManager->getConnectedGrid()->isSecondLife();
// if (mHost != LLHost::invalid) use_http = false; // if (mHost != LLHost::invalid) use_http = false;
if (use_http && mCanUseHTTP && mUrl.empty()) // get http url. if ((is_sl || use_http) && mCanUseHTTP && mUrl.empty()) // get http url.
{ {
LLViewerRegion* region = NULL; LLViewerRegion* region = NULL;
if (mHost == LLHost::invalid) if (mHost == LLHost::invalid)
@@ -1280,6 +1281,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
mWriteToCacheState = CAN_WRITE; mWriteToCacheState = CAN_WRITE;
} }
if (!mUrl.empty() && SGHostBlackList::isBlacklisted(mUrl)){ if (!mUrl.empty() && SGHostBlackList::isBlacklisted(mUrl)){
LL_DEBUGS("Texture") << mID << "Blacklisted" << LL_ENDL;
mCanUseHTTP = false; mCanUseHTTP = false;
} }
if (mCanUseHTTP && !mUrl.empty()) if (mCanUseHTTP && !mUrl.empty())
@@ -1292,7 +1294,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
} }
// don't return, fall through to next state // don't return, fall through to next state
} }
else if (mSentRequest == UNSENT && mCanUseNET) else if (!mCanUseNET)
{
LL_WARNS(LOG_TXT) << mID << "Unable to retrieve texture via HTTP and UDP unavailable (probable 404): " << mUrl << LL_ENDL;
return true;
}
else if (mSentRequest == UNSENT)
{ {
LL_DEBUGS("Texture") << mID << " moving to UDP fetch. mSentRequest=" << mSentRequest << " mCanUseNET = " << mCanUseNET << LL_ENDL; LL_DEBUGS("Texture") << mID << " moving to UDP fetch. mSentRequest=" << mSentRequest << " mCanUseNET = " << mCanUseNET << LL_ENDL;
setState(SEND_UDP_REQ); setState(SEND_UDP_REQ);
@@ -1821,6 +1828,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
S32 discard = mHaveAllData ? 0 : mLoadedDiscard; S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority; U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
mDecoded = FALSE; mDecoded = FALSE;
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
setState(DECODE_IMAGE_UPDATE); setState(DECODE_IMAGE_UPDATE);
LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
<< " All Data: " << mHaveAllData << LL_ENDL; << " All Data: " << mHaveAllData << LL_ENDL;

View File

@@ -244,18 +244,19 @@ void LLToolBar::updateCommunicateList()
bold_if_equal(LLFloaterMyFriends::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterMyFriends::getInstance()->getShortTitle(), LLSD("contacts"), ADD_TOP)); bold_if_equal(LLFloaterMyFriends::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterMyFriends::getInstance()->getShortTitle(), LLSD("contacts"), ADD_TOP));
bold_if_equal(LLFloaterChat::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterChat::getInstance()->getShortTitle(), LLSD("local chat"), ADD_TOP)); bold_if_equal(LLFloaterChat::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterChat::getInstance()->getShortTitle(), LLSD("local chat"), ADD_TOP));
mCommunicateBtn->addSeparator(ADD_TOP); mCommunicateBtn->addSeparator(ADD_TOP);
mCommunicateBtn->add(getString("Redock Windows"), LLSD("redock"), ADD_TOP); static const auto redock = getString("Redock Windows");
mCommunicateBtn->add(redock, LLSD("redock"), ADD_TOP);
mCommunicateBtn->addSeparator(ADD_TOP); mCommunicateBtn->addSeparator(ADD_TOP);
bold_if_equal(LLFloaterMute::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterMute::getInstance()->getShortTitle(), LLSD("mute list"), ADD_TOP)); bold_if_equal(LLFloaterMute::getInstance(), frontmost_floater, mCommunicateBtn->add(LLFloaterMute::getInstance()->getShortTitle(), LLSD("mute list"), ADD_TOP));
if (gIMMgr->getIMFloaterHandles().size() > 0) mCommunicateBtn->addSeparator(ADD_TOP); if (gIMMgr->getIMFloaterHandles().size() > 0) mCommunicateBtn->addSeparator(ADD_TOP);
for(std::set<LLHandle<LLFloater> >::const_iterator floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it) for(const auto& handle : gIMMgr->getIMFloaterHandles())
{ {
if (LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)floater_handle_it->get()) if (LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)handle.get())
{ {
const S32 count = im_floaterp->getNumUnreadMessages(); const S32 count = im_floaterp->getNumUnreadMessages();
std::string floater_title; std::string floater_title;
if (count > 0) floater_title = "*"; if (count > 0) floater_title = '*';
floater_title.append(im_floaterp->getShortTitle()); floater_title.append(im_floaterp->getShortTitle());
static const LLCachedControl<bool> show_counts("ShowUnreadIMsCounts", true); static const LLCachedControl<bool> show_counts("ShowUnreadIMsCounts", true);
if (show_counts && count > 0) if (show_counts && count > 0)
@@ -265,11 +266,14 @@ void LLToolBar::updateCommunicateList()
{ {
LLStringUtil::format_map_t args; LLStringUtil::format_map_t args;
args["COUNT"] = llformat("%d", count); args["COUNT"] = llformat("%d", count);
floater_title += getString("IMs", args); static LLUIString ims = getString("IMs");
ims.setArgList(args);
floater_title += ims.getString();
} }
else else
{ {
floater_title += getString("IM"); static const auto im = getString("IM");
floater_title += im;
} }
} }
bold_if_equal(im_floaterp, frontmost_floater, mCommunicateBtn->add(floater_title, im_floaterp->getSessionID(), ADD_TOP)); bold_if_equal(im_floaterp, frontmost_floater, mCommunicateBtn->add(floater_title, im_floaterp->getSessionID(), ADD_TOP));

View File

@@ -1368,8 +1368,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
LLMute mute(blocked_id, full_name, mute_type); LLMute mute(blocked_id, full_name, mute_type);
if (LLMuteList::getInstance()->add(mute)) if (LLMuteList::getInstance()->add(mute))
{ {
LLFloaterMute::showInstance(); LLFloaterMute::showInstance()->selectMute(blocked_id);
LLFloaterMute::getInstance()->selectMute(blocked_id);
} }
// purge the message queue of any previously queued inventory offers from the same source. // purge the message queue of any previously queued inventory offers from the same source.

View File

@@ -54,4 +54,4 @@
<on_click function="List.CopySLURL"/> <on_click function="List.CopySLURL"/>
<on_visible function="List.EnableSingleSelected"/> <on_visible function="List.EnableSingleSelected"/>
</menu_item_call> </menu_item_call>
</menu> </context_menu>

View File

@@ -9950,7 +9950,7 @@ You cannot copy your selection because the object '[OBJ_NAME]' is not transferra
name="NoPermsNoRemoval" name="NoPermsNoRemoval"
type="notify"> type="notify">
<tag>fail</tag> <tag>fail</tag>
Removal of the object '[OBJ_NAME]' from the simulator is disallowed by the permissions system. Removal of the object '[OBJ_NAME]' from the region is disallowed by the permissions system.
</notification> </notification>
<notification <notification
@@ -10221,7 +10221,7 @@ Unable to add script!
name="AssetServerTimeoutObjReturn" name="AssetServerTimeoutObjReturn"
type="notify"> type="notify">
<tag>fail</tag> <tag>fail</tag>
Asset server didn't respond in a timely fashion. Object returned to sim. Asset server didn't respond in a timely fashion. Object returned to region.
</notification> </notification>
<notification <notification
@@ -11694,7 +11694,7 @@ Media/audio URL blocked for [DOMAIN]
name="RadarChatKeysRequest" name="RadarChatKeysRequest"
type="alertmodal"> type="alertmodal">
An object owned by you has requested keys from your radar. An object owned by you has requested keys from your radar.
Would you like to enable announcing keys to objects in the sim? Would you like to enable announcing keys to objects in the region?
<usetemplate <usetemplate
name="yesnocancelbuttons" name="yesnocancelbuttons"
yestext="Yes" yestext="Yes"

View File

@@ -80,8 +80,8 @@
<button bottom_delta="0" left="146" height="16" width="16" follows="left|bottom" image_overlay="inv_folder_trash.tga" scale_image="true" label="" tool_tip="Delete the currently selected remembered login info, if any." name="remove_login"/> <button bottom_delta="0" left="146" height="16" width="16" follows="left|bottom" image_overlay="inv_folder_trash.tga" scale_image="true" label="" tool_tip="Delete the currently selected remembered login info, if any." name="remove_login"/>
<check_box bottom_delta="0" left="173" control_name="RememberPassword" follows="left|bottom" height="16" label="Save password" name="remember_check" width="158"/> <check_box bottom_delta="0" left="173" control_name="RememberPassword" follows="left|bottom" height="16" label="Save password" name="remember_check" width="158"/>
<text name="fmod_text" value="Powered By" bottom="42" height="16" left="-425" width="84" follows="right|bottom" font="SansSerif" font_style="BOLD" font_size="Large"/> <icon name="fmod_logo" bottom="10" height="40" left="-341" width="152" follows="right|bottom" image_name="FMOD_Logo"/>
<icon name="fmod_logo" bottom_delta="-32" height="40" left_delta="84" width="152" follows="right|bottom" image_name="FMOD_Logo"/> <text name="fmod_text" value="Powered By" bottom_delta="40" height="16" left_delta="36" width="84" follows="right|bottom" font="SansSerif" font_style="BOLD" font_size="Large"/>
<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false" <text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom="45" drop_shadow_visible="true" follows="right|bottom" bottom="45" drop_shadow_visible="true" follows="right|bottom"

View File

@@ -115,8 +115,9 @@
<spinner bottom_delta="0" decimal_digits="0" follows="top" height="16" increment="1" left_delta="210" max_val="9999" min_val="1" name="ScriptJumpCount" width="50" control_name="Ascentnumscriptdiff" tool_tip="Threshold for the script jump message [Default: 100]"/> <spinner bottom_delta="0" decimal_digits="0" follows="top" height="16" increment="1" left_delta="210" max_val="9999" min_val="1" name="ScriptJumpCount" width="50" control_name="Ascentnumscriptdiff" tool_tip="Threshold for the script jump message [Default: 100]"/>
<check_box bottom_delta="-20" left="10" follows="top" label="Restrained Love API Support (RLVa)" name="RestrainedLove" control_name="RestrainedLove" tool_tip="Allows scripts to take greater control of the viewer, if you wear compliant objects."/> <check_box bottom_delta="-20" left="10" follows="top" label="Restrained Love API Support (RLVa)" name="RestrainedLove" control_name="RestrainedLove" tool_tip="Allows scripts to take greater control of the viewer, if you wear compliant objects."/>
<check_box bottom_delta="-20" follows="top" label="Replace slurls and formatted links with labels" name="SinguReplaceLinks" control_name="SinguReplaceLinks" tool_tip="While you can right click to see where they really lead by copying them, this does allow links to be misleading at first glance."/> <check_box bottom_delta="-20" follows="top" label="Replace slurls and formatted links with labels" name="SinguReplaceLinks" control_name="SinguReplaceLinks" tool_tip="While you can right click to see where they really lead by copying them, this does allow links to be misleading at first glance."/>
<text name="EmergencyTeleportDesc" left="14" bottom_delta="-12" follows="top">Drop a landmark below to autoteleport there in the last 20 seconds before region restarts</text> <text name="EmergencyTeleportDesc" left="14" bottom_delta="-12" follows="top">Drop a landmark below to autoteleport to before region restarts</text>
<drop_target control_name="EmergencyTeleportLandmark" bottom_delta="-8" left="15" height="17" name="emergency_teleport_landmark_drop" width="430"/> <spinner name="EmergencyTeleportSeconds" label="Seconds before restart to begin teleport attempts" label_width="380" width="432" control_name="EmergencyTeleportSeconds" bottom_delta="-26" decimal_digits="0" max_val="3600" min_val="0" follows="left|top" height="18" increment="1"/>
<drop_target control_name="EmergencyTeleportLandmark" bottom_delta="-4" left="15" height="17" name="emergency_teleport_landmark_drop" width="430"/>
<text name="EmergencyTeleportBackupDesc" halign="center" width="432" left="14" bottom_delta="-26" follows="top">Drop a backup landmark to autoteleport to below, should you already be at above</text> <text name="EmergencyTeleportBackupDesc" halign="center" width="432" left="14" bottom_delta="-26" follows="top">Drop a backup landmark to autoteleport to below, should you already be at above</text>
<drop_target control_name="EmergencyTeleportLandmarkBackup" bottom_delta="-8" left="15" height="17" name="emergency_teleport_landmark_backup_drop" width="430"/> <drop_target control_name="EmergencyTeleportLandmarkBackup" bottom_delta="-8" left="15" height="17" name="emergency_teleport_landmark_backup_drop" width="430"/>
</panel> </panel>

View File

@@ -22,6 +22,8 @@
<column name="Owner" label="Propietario" tool_tip="Haz doble click en cualquier resultado para marcar su posición"/> <column name="Owner" label="Propietario" tool_tip="Haz doble click en cualquier resultado para marcar su posición"/>
<column name="Group" label="Grupo" tool_tip="Haz doble click en cualquier resultado para marcar su posición"/> <column name="Group" label="Grupo" tool_tip="Haz doble click en cualquier resultado para marcar su posición"/>
</scroll_list> </scroll_list>
<button name="TP" label="TP"/>
<button name="Look" label="Ver"/>
<text name="counter"> <text name="counter">
Listados/Pendientes/Total Listados/Pendientes/Total
</text> </text>

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<menu label="Grupos" name="groups_menu"> <menu label="Grupos" name="groups_menu">
<menu_item_call label="Mostrar Perfil" name="show_group"/> <menu_item_call label="Mostrar Información del Grupo" name="show_group"/>
<menu_item_call label="Abrir chat del grupo" name="im_group"/> <menu_item_call label="Abrir chat del grupo" name="im_group"/>
<menu_item_call label="LLamar en el grupo" name="call_group"/> <menu_item_call label="Abrir chat del Grupo" name="call_group"/>
<menu_item_call label="Activar Grupo" name="activate_group"/> <menu_item_call label="Activar Grupo" name="activate_group"/>
<menu_item_call label="Hisotiral de chat" name="Chat History"/> <menu_item_call label="Historial de chat" name="Chat History"/>
<menu_item_call label="Unirse al Grupo" name="join_group"/> <menu_item_call label="Unirse al Grupo" name="join_group"/>
<menu_item_call label="Abandonar el Grupo" name="leave_group"/> <menu_item_call label="Abandonar el Grupo" name="leave_group"/>
<menu_item_call label="Copiar Nombre" name="copy_name"/> <menu_item_call label="Copiar Nombre" name="copy_name"/>

View File

@@ -1,27 +1,31 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<menu label="Propietario" name="Object Owner Submenu"> <menu label="Propietario" name="Object Owner Submenu">
<menu_item_call label="Perfil" name="Profile"/> <menu_item_call label="Perfil" name="Profile"/>
<menu name="Acciones" label="Actions"/> <menu name="Actions" label="Acciones">
<menu_item_call label="Pagar" name="Pay"/> <menu_item_call label="Perfil Web" name="Web Profile"/>
<menu_item_call label="Mensaje Instantáneo" name="Instant Message"/> <menu_item_call label="Pagar" name="Pay"/>
<menu_item_call label="Conferencia" name="Conference Chat"/> <menu_item_call label="Mensaje Instantáneo" name="Instant Message"/>
<menu_item_call label="Llamar" name="Call"/> <menu_item_call label="Conferencia" name="Conference Chat"/>
<menu_item_call label="Llamar Conferencia" name="Conference Call"/> <menu_item_call label="Llamar" name="Call"/>
<menu_item_call label="Ofrecer Amistad" name="Add Friend"/> <menu_item_call label="Llamar Conferencia" name="Conference Call"/>
<menu_item_call label="Quitar Amistad" name="Remove Friend"/> <menu_item_call label="Ofrecer Amistad" name="Add Friend"/>
<menu_item_call label="Invitar a un Grupo" name="Invite To Group"/> <menu_item_call label="Quitar Amistad" name="Remove Friend"/>
<menu_item_call label="Seguir" name="Follow"/> <menu_item_call label="Invitar a un Grupo" name="Invite To Group"/>
<menu_item_call label="Movea A" name="Move To"/> <menu_item_call label="Seguir" name="Follow"/>
<menu_item_call label="Ofrecer Teleporte" name="Offer Teleport"/> <menu_item_call label="Mover A" name="Move To"/>
<menu_item_call label="Teleportar A" name="Teleport To"/> <menu_item_call label="Ofrecer Teleporte" name="Offer Teleport"/>
<menu_item_call label="Solicitar Teleporte" name="Request Teleport"/> <menu_item_call label="Teleportar A" name="Teleport To"/>
<menu_item_call label="Encontrar en el Mapa" name="Find on Map"/> <menu_item_call label="Solicitar Teleporte" name="Request Teleport"/>
<menu_item_call label="Compartir" name="Share"/> <menu_item_call label="Encontrar en el Mapa" name="Find on Map"/>
<menu_item_call label="Historial de Chat" name="Chat History"/> <menu_item_call label="Compartir" name="Share"/>
<menu_item_call label="Rastrear/No Rastrear" name="Track/Untrack"/> <menu_item_call label="Historial de Chat" name="Chat History"/>
<menu name="Copiar" label="Copy"/> <menu_item_call label="Rastrear/No Rastrear" name="Track/Untrack"/>
<menu_item_call label="Nombre" name="Copy Name"/> </menu>
<menu_item_call label="SLURL" name="Copy SLURL"/> <menu name="Copy" label="Copiar">
<menu_item_call label="UUID" name="Copy Key"/>
<menu_item_call label="Nombre" name="Copy Name"/>
<menu_item_call label="SLURL" name="Copy SLURL"/>
</menu>
<menu_item_call label="Enfocar" name="Focus"/> <menu_item_call label="Enfocar" name="Focus"/>
<menu label="Moderación" name="Moderation" create_jump_keys=""> <menu label="Moderación" name="Moderation" create_jump_keys="">
<menu_item_call label="Silenciar" name="Mute"/> <menu_item_call label="Silenciar" name="Mute"/>

View File

@@ -1,8 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<context_menu name="Url Popup"> <context_menu label="Grupo" name="Url Popup">
<menu_item_call label="Mostrar la información del grupo" name="show_group"/> <menu_item_call label="Mostrar la información del grupo" name="show_group"/>
<menu_item_call label="Abrir chat del grupo" name="im_group"/>
<menu_item_call label="Llamar en el grupo" name="call_group"/>
<menu_item_call label="Activar Grupo" name="activate_group"/>
<menu_item_call label="Historial de Chat" name="Chat History"/>
<menu_item_call label="Unirse al Grupo" name="join_group"/>
<menu_item_call label="Abandonar el Grupo" name="leave_group"/>
<menu_item_call label="Copiar el grupo al portapapeles" name="url_copy_label"/> <menu_item_call label="Copiar el grupo al portapapeles" name="url_copy_label"/>
<menu_item_call label="Copiar SLurl al portapapeles" name="url_copy"/> <menu_item_call label="Copiar SLurl al portapapeles" name="url_copy"/>
<menu_item_call label="Copiar Key al portapapeles" name="key_copy"/> <menu_item_call label="Copiar UUID al portapapeles" name="key_copy"/>
<menu_item_call label="Seleccionar Todo" name="Select All"/> <menu_item_call label="Seleccionar Todo" name="Select All"/>
</context_menu> </context_menu>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu label="Propietario" name="Object Owner Submenu"> <context_menu label="Propietario" name="Object Owner Submenu">
<menu_item_call label="Enviar MI..." name="send_im"/> <menu_item_call label="Enviar MI..." name="send_im"/>
<menu name="Acciones" label="Actions"> <menu name="Actions" label="Acciones">
<menu_item_call label="Perfil" name="Profile"/> <menu_item_call label="Perfil" name="Profile"/>
<menu_item_call label="Perfil Web" name="Web Profile"/> <menu_item_call label="Perfil Web" name="Web Profile"/>
<menu_item_call label="Pagar" name="Pay"/> <menu_item_call label="Pagar" name="Pay"/>

View File

@@ -135,7 +135,8 @@
<spinner left_delta="270" name="ScriptJumpCount" tool_tip="Umbral para el mensaje de salto de scripts [Predeterminado: 100]"/> <spinner left_delta="270" name="ScriptJumpCount" tool_tip="Umbral para el mensaje de salto de scripts [Predeterminado: 100]"/>
<check_box label="Soporte API Restrained Love (RLVa)" name="RestrainedLove" tool_tip="Permite a los scripts tomar control del visor, si tienes vestido un objeto compatible con RLVa."/> <check_box label="Soporte API Restrained Love (RLVa)" name="RestrainedLove" tool_tip="Permite a los scripts tomar control del visor, si tienes vestido un objeto compatible con RLVa."/>
<check_box label="Reemplazar slurls y enlaces con etiquetas" name="SinguReplaceLinks" tool_tip="Si bien puedes hacer clic con el botón derecho para ver a dónde conducen realmente al copiarlos, esto puede hacer que los enlaces sean confusos a primera vista."/> <check_box label="Reemplazar slurls y enlaces con etiquetas" name="SinguReplaceLinks" tool_tip="Si bien puedes hacer clic con el botón derecho para ver a dónde conducen realmente al copiarlos, esto puede hacer que los enlaces sean confusos a primera vista."/>
<text name="EmergencyTeleportDesc" bottom_delta="-20" >Arrastra un hito para autoteleportarte en los últimos 20 segundos previos al reinicio de región</text> <text name="EmergencyTeleportDesc" bottom_delta="-20" >Arrastra un hito debajo para autoteleportarte antes del reinicio de la región</text>
<spinner name="EmergencyTeleportSeconds" label="Comenzar intentos de teleporte antes del reinicio, en segundos"/>
<drop_target name="emergency_teleport_landmark_drop" bottom_delta="-15" width="450"/> <drop_target name="emergency_teleport_landmark_drop" bottom_delta="-15" width="450"/>
<text name="EmergencyTeleportBackupDesc" width="440" bottom_delta="-30" > <text name="EmergencyTeleportBackupDesc" width="440" bottom_delta="-30" >
Suelta aquí un hito de resguardo para autoteleportarte, si ya tienes uno en el ítem anterior</text> Suelta aquí un hito de resguardo para autoteleportarte, si ya tienes uno en el ítem anterior</text>