This commit is contained in:
Shyotl
2020-04-08 18:18:19 -05:00
19 changed files with 397 additions and 650 deletions

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

@@ -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

@@ -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

@@ -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

@@ -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.
mute_set_t::iterator it = mMutes.find(localmute);
if (it != mMutes.end())
{
// 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
{
// There was no entry in the list previously. Fake things up by making it look like the previous entry had all properties unmuted.
localmute.mFlags = LLMute::flagAll;
}
if(flags) if(flags)
{ {
// The user passed some combination of flags. Make sure those flag bits are turned off (i.e. those properties will be muted). // 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); localmute.mFlags &= (~flags);
} }
else else
{ {
// The user passed 0. Make sure all flag bits are turned off (i.e. all properties will be muted). // The user passed 0. Make sure all flag bits are turned off (i.e. all properties will be muted).
localmute.mFlags = 0; localmute.mFlags = 0;
} }
// (re)add the mute entry. // (re)add the mute entry.
{ {
std::pair<mute_set_t::iterator, bool> result = mMutes.insert(localmute); auto result = mMutes.insert(localmute);
if (result.second) if (result.second)
{
LL_INFOS() << "Muting " << localmute.mName << " id " << localmute.mID << " flags " << localmute.mFlags << LL_ENDL;
updateAdd(localmute);
notifyObservers();
notifyObserversDetailed(localmute);
if(!(localmute.mFlags & LLMute::flagParticles))
{ {
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

@@ -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

@@ -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"