Merge branch 'release/2025.06' of https://github.com/secondlife/viewer
# Conflicts: # indra/llui/llurlentry.cpp # indra/newview/llfloatermodelpreview.cpp # indra/newview/llvoavatar.cppmaster
commit
0871a8ed4a
|
|
@ -1073,6 +1073,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
||||||
// TODO - figure out if this should be moved into the noclobber fields above
|
// TODO - figure out if this should be moved into the noclobber fields above
|
||||||
mThumbnailUUID.setNull();
|
mThumbnailUUID.setNull();
|
||||||
mFavorite = false;
|
mFavorite = false;
|
||||||
|
mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
|
||||||
|
|
||||||
// iterate as map to avoid making unnecessary temp copies of everything
|
// iterate as map to avoid making unnecessary temp copies of everything
|
||||||
LLSD::map_const_iterator i, end;
|
LLSD::map_const_iterator i, end;
|
||||||
|
|
@ -1131,7 +1132,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
||||||
|
|
||||||
if (i->first == INV_PERMISSIONS_LABEL)
|
if (i->first == INV_PERMISSIONS_LABEL)
|
||||||
{
|
{
|
||||||
mPermissions = ll_permissions_from_sd(i->second);
|
mPermissions.importLLSD(i->second);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1600,53 +1601,68 @@ void LLInventoryCategory::exportLLSD(LLSD& cat_data) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
|
bool LLInventoryCategory::importLLSDMap(const LLSD& cat_data)
|
||||||
{
|
{
|
||||||
if (cat_data.has(INV_FOLDER_ID_LABEL))
|
LLSD::map_const_iterator i, end;
|
||||||
|
end = cat_data.endMap();
|
||||||
|
for ( i = cat_data.beginMap(); i != end; ++i)
|
||||||
{
|
{
|
||||||
setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID());
|
importLLSD(i->first, i->second);
|
||||||
}
|
}
|
||||||
if (cat_data.has(INV_PARENT_ID_LABEL))
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLInventoryCategory::importLLSD(const std::string& label, const LLSD& value)
|
||||||
|
{
|
||||||
|
if (label == INV_FOLDER_ID_LABEL)
|
||||||
{
|
{
|
||||||
setParent(cat_data[INV_PARENT_ID_LABEL].asUUID());
|
setUUID(value.asUUID());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (cat_data.has(INV_ASSET_TYPE_LABEL))
|
else if (label == INV_PARENT_ID_LABEL)
|
||||||
{
|
{
|
||||||
setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString()));
|
setParent(value.asUUID());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (cat_data.has(INV_PREFERRED_TYPE_LABEL))
|
else if (label == INV_ASSET_TYPE_LABEL)
|
||||||
{
|
{
|
||||||
setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString()));
|
setType(LLAssetType::lookup(value.asString()));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (cat_data.has(INV_THUMBNAIL_LABEL))
|
else if (label == INV_PREFERRED_TYPE_LABEL)
|
||||||
|
{
|
||||||
|
setPreferredType(LLFolderType::lookup(value.asString()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (label == INV_THUMBNAIL_LABEL)
|
||||||
{
|
{
|
||||||
LLUUID thumbnail_uuid;
|
LLUUID thumbnail_uuid;
|
||||||
const LLSD &thumbnail_data = cat_data[INV_THUMBNAIL_LABEL];
|
if (value.has(INV_ASSET_ID_LABEL))
|
||||||
if (thumbnail_data.has(INV_ASSET_ID_LABEL))
|
|
||||||
{
|
{
|
||||||
thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID();
|
thumbnail_uuid = value[INV_ASSET_ID_LABEL].asUUID();
|
||||||
}
|
}
|
||||||
setThumbnailUUID(thumbnail_uuid);
|
setThumbnailUUID(thumbnail_uuid);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (cat_data.has(INV_FAVORITE_LABEL))
|
if (label == INV_FAVORITE_LABEL)
|
||||||
{
|
{
|
||||||
bool favorite = false;
|
bool favorite = false;
|
||||||
const LLSD& favorite_data = cat_data[INV_FAVORITE_LABEL];
|
if (value.has(INV_TOGGLED_LABEL))
|
||||||
if (favorite_data.has(INV_TOGGLED_LABEL))
|
|
||||||
{
|
{
|
||||||
favorite = favorite_data[INV_TOGGLED_LABEL].asBoolean();
|
favorite = value[INV_TOGGLED_LABEL].asBoolean();
|
||||||
}
|
}
|
||||||
setFavorite(favorite);
|
setFavorite(favorite);
|
||||||
}
|
}
|
||||||
if (cat_data.has(INV_NAME_LABEL))
|
else if (label == INV_NAME_LABEL)
|
||||||
{
|
{
|
||||||
mName = cat_data[INV_NAME_LABEL].asString();
|
mName = value.asString();
|
||||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||||
LLStringUtil::replaceChar(mName, '|', ' ');
|
LLStringUtil::replaceChar(mName, '|', ' ');
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///----------------------------------------------------------------------------
|
///----------------------------------------------------------------------------
|
||||||
/// Local function definitions for testing purposes
|
/// Local function definitions for testing purposes
|
||||||
///----------------------------------------------------------------------------
|
///----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,8 @@ public:
|
||||||
virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
|
virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
|
||||||
|
|
||||||
virtual void exportLLSD(LLSD& sd) const;
|
virtual void exportLLSD(LLSD& sd) const;
|
||||||
bool importLLSD(const LLSD& cat_data);
|
bool importLLSDMap(const LLSD& cat_data);
|
||||||
|
virtual bool importLLSD(const std::string& label, const LLSD& value);
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Member Variables
|
// Member Variables
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -704,6 +704,79 @@ bool LLPermissions::exportLegacyStream(std::ostream& output_stream) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const std::string PERM_CREATOR_ID_LABEL("creator_id");
|
||||||
|
static const std::string PERM_OWNER_ID_LABEL("owner_id");
|
||||||
|
static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
|
||||||
|
static const std::string PERM_GROUP_ID_LABEL("group_id");
|
||||||
|
static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
|
||||||
|
static const std::string PERM_BASE_MASK_LABEL("base_mask");
|
||||||
|
static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
|
||||||
|
static const std::string PERM_GROUP_MASK_LABEL("group_mask");
|
||||||
|
static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
|
||||||
|
static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
|
||||||
|
|
||||||
|
void LLPermissions::importLLSD(const LLSD& sd_perm)
|
||||||
|
{
|
||||||
|
LLSD::map_const_iterator i, end;
|
||||||
|
end = sd_perm.endMap();
|
||||||
|
for (i = sd_perm.beginMap(); i != end; ++i)
|
||||||
|
{
|
||||||
|
const std::string& label = i->first;
|
||||||
|
if (label == PERM_CREATOR_ID_LABEL)
|
||||||
|
{
|
||||||
|
mCreator = i->second.asUUID();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (label == PERM_OWNER_ID_LABEL)
|
||||||
|
{
|
||||||
|
mOwner = i->second.asUUID();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (label == PERM_LAST_OWNER_ID_LABEL)
|
||||||
|
{
|
||||||
|
mLastOwner = i->second.asUUID();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (label == PERM_GROUP_ID_LABEL)
|
||||||
|
{
|
||||||
|
mGroup = i->second.asUUID();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (label == PERM_BASE_MASK_LABEL)
|
||||||
|
{
|
||||||
|
PermissionMask mask = i->second.asInteger();
|
||||||
|
mMaskBase = mask;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (label == PERM_OWNER_MASK_LABEL)
|
||||||
|
{
|
||||||
|
PermissionMask mask = i->second.asInteger();
|
||||||
|
mMaskOwner = mask;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (label == PERM_EVERYONE_MASK_LABEL)
|
||||||
|
{
|
||||||
|
PermissionMask mask = i->second.asInteger();
|
||||||
|
mMaskEveryone = mask;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (label == PERM_GROUP_MASK_LABEL)
|
||||||
|
{
|
||||||
|
PermissionMask mask = i->second.asInteger();
|
||||||
|
mMaskGroup = mask;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (label == PERM_NEXT_OWNER_MASK_LABEL)
|
||||||
|
{
|
||||||
|
PermissionMask mask = i->second.asInteger();
|
||||||
|
mMaskNextOwner = mask;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fix();
|
||||||
|
}
|
||||||
|
|
||||||
bool LLPermissions::operator==(const LLPermissions &rhs) const
|
bool LLPermissions::operator==(const LLPermissions &rhs) const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
@ -1016,16 +1089,6 @@ std::string mask_to_string(U32 mask, bool isOpenSim /*=false*/) // <FS:Beq/> rem
|
||||||
///----------------------------------------------------------------------------
|
///----------------------------------------------------------------------------
|
||||||
/// exported functions
|
/// exported functions
|
||||||
///----------------------------------------------------------------------------
|
///----------------------------------------------------------------------------
|
||||||
static const std::string PERM_CREATOR_ID_LABEL("creator_id");
|
|
||||||
static const std::string PERM_OWNER_ID_LABEL("owner_id");
|
|
||||||
static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
|
|
||||||
static const std::string PERM_GROUP_ID_LABEL("group_id");
|
|
||||||
static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
|
|
||||||
static const std::string PERM_BASE_MASK_LABEL("base_mask");
|
|
||||||
static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
|
|
||||||
static const std::string PERM_GROUP_MASK_LABEL("group_mask");
|
|
||||||
static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
|
|
||||||
static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
|
|
||||||
|
|
||||||
LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
|
LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
|
||||||
{
|
{
|
||||||
|
|
@ -1050,25 +1113,6 @@ void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm)
|
||||||
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)
|
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)
|
||||||
{
|
{
|
||||||
LLPermissions rv;
|
LLPermissions rv;
|
||||||
rv.init(
|
rv.importLLSD(sd_perm);
|
||||||
sd_perm[PERM_CREATOR_ID_LABEL].asUUID(),
|
|
||||||
sd_perm[PERM_OWNER_ID_LABEL].asUUID(),
|
|
||||||
sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(),
|
|
||||||
sd_perm[PERM_GROUP_ID_LABEL].asUUID());
|
|
||||||
|
|
||||||
// We do a cast to U32 here since LLSD does not attempt to
|
|
||||||
// represent unsigned ints.
|
|
||||||
PermissionMask mask;
|
|
||||||
mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger());
|
|
||||||
rv.setMaskBase(mask);
|
|
||||||
mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger());
|
|
||||||
rv.setMaskOwner(mask);
|
|
||||||
mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger());
|
|
||||||
rv.setMaskEveryone(mask);
|
|
||||||
mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger());
|
|
||||||
rv.setMaskGroup(mask);
|
|
||||||
mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger());
|
|
||||||
rv.setMaskNext(mask);
|
|
||||||
rv.fix();
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,8 @@ public:
|
||||||
bool importLegacyStream(std::istream& input_stream);
|
bool importLegacyStream(std::istream& input_stream);
|
||||||
bool exportLegacyStream(std::ostream& output_stream) const;
|
bool exportLegacyStream(std::ostream& output_stream) const;
|
||||||
|
|
||||||
|
void importLLSD(const LLSD& sd_perm);
|
||||||
|
|
||||||
bool operator==(const LLPermissions &rhs) const;
|
bool operator==(const LLPermissions &rhs) const;
|
||||||
bool operator!=(const LLPermissions &rhs) const;
|
bool operator!=(const LLPermissions &rhs) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -518,7 +518,7 @@ namespace tut
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
|
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
|
||||||
src2->importLLSD(s_item);
|
src2->importLLSDMap(s_item);
|
||||||
|
|
||||||
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
|
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
|
||||||
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
|
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,16 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string LLUrlAction::getURLLabel(std::string url)
|
||||||
|
{
|
||||||
|
LLUrlMatch match;
|
||||||
|
if (LLUrlRegistry::instance().findUrl(url, match))
|
||||||
|
{
|
||||||
|
return match.getLabel();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
void LLUrlAction::showProfile(std::string url)
|
void LLUrlAction::showProfile(std::string url)
|
||||||
{
|
{
|
||||||
// Get id from 'secondlife:///app/{cmd}/{id}/{action}'
|
// Get id from 'secondlife:///app/{cmd}/{id}/{action}'
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@ public:
|
||||||
/// copy a Url to the clipboard
|
/// copy a Url to the clipboard
|
||||||
static void copyURLToClipboard(std::string url);
|
static void copyURLToClipboard(std::string url);
|
||||||
|
|
||||||
|
static std::string getURLLabel(std::string url);
|
||||||
|
|
||||||
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
|
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
|
||||||
static void showProfile(std::string url);
|
static void showProfile(std::string url);
|
||||||
static std::string getUserID(std::string url);
|
static std::string getUserID(std::string url);
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,6 @@
|
||||||
#include "llexperiencecache.h"
|
#include "llexperiencecache.h"
|
||||||
#include "v3dmath.h"
|
#include "v3dmath.h"
|
||||||
|
|
||||||
// <FS:AW> hop:// protocol>
|
|
||||||
//#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
|
|
||||||
#define APP_HEADER_REGEX "(((hop|x-grid-location-info)://[-\\w\\.\\:\\@]+/app)|((hop|secondlife):///app))"
|
|
||||||
// </FS:AW>
|
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
|
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@
|
||||||
class LLAvatarName;
|
class LLAvatarName;
|
||||||
class LLVector3d;
|
class LLVector3d;
|
||||||
|
|
||||||
|
// <FS:AW> hop:// protocol>
|
||||||
|
//#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
|
||||||
|
#define APP_HEADER_REGEX "(((hop|x-grid-location-info)://[-\\w\\.\\:\\@]+/app)|((hop|secondlife):///app))"
|
||||||
|
// </FS:AW>
|
||||||
|
|
||||||
typedef boost::signals2::signal<void (const std::string& url,
|
typedef boost::signals2::signal<void (const std::string& url,
|
||||||
const std::string& label,
|
const std::string& label,
|
||||||
const std::string& icon)> LLUrlLabelSignal;
|
const std::string& icon)> LLUrlLabelSignal;
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ bool LLFloaterModelPreview::postBuild()
|
||||||
for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
|
for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
|
||||||
{
|
{
|
||||||
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]);
|
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]);
|
||||||
lod_source_combo->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLoDSourceCommit, this, lod, true));
|
lod_source_combo->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLoDSourceCommit, this, lod));
|
||||||
lod_source_combo->setCurrentByIndex(mLODMode[lod]);
|
lod_source_combo->setCurrentByIndex(mLODMode[lod]);
|
||||||
|
|
||||||
getChild<LLButton>("lod_browse_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onBrowseLOD, this, lod));
|
getChild<LLButton>("lod_browse_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onBrowseLOD, this, lod));
|
||||||
|
|
@ -858,7 +858,7 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
|
||||||
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[i]);
|
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[i]);
|
||||||
if (lod_source_combo->getCurrentIndex() == LLModelPreview::USE_LOD_ABOVE)
|
if (lod_source_combo->getCurrentIndex() == LLModelPreview::USE_LOD_ABOVE)
|
||||||
{
|
{
|
||||||
onLoDSourceCommit(i, false);
|
onLoDSourceCommit(i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1943,7 +1943,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLFloaterModelPreview::onLoDSourceCommit(S32 lod, bool refresh_ui)
|
void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
|
||||||
{
|
{
|
||||||
mModelPreview->updateLodControls(lod);
|
mModelPreview->updateLodControls(lod);
|
||||||
|
|
||||||
|
|
@ -1969,12 +1969,10 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod, bool refresh_ui)
|
||||||
// rebuild LoD to update triangle counts
|
// rebuild LoD to update triangle counts
|
||||||
onLODParamCommit(lod, true);
|
onLODParamCommit(lod, true);
|
||||||
}
|
}
|
||||||
else if (refresh_ui && index == LLModelPreview::USE_LOD_ABOVE)
|
if (index == LLModelPreview::USE_LOD_ABOVE)
|
||||||
{
|
{
|
||||||
// Update mUploadData for updateStatusMessages
|
// refresh to pick triangle counts
|
||||||
mModelPreview->rebuildUploadData();
|
mModelPreview->mDirty = true;
|
||||||
// Update UI with new triangle values
|
|
||||||
mModelPreview->updateStatusMessages();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ private:
|
||||||
void onClickCalculateBtn();
|
void onClickCalculateBtn();
|
||||||
void onJointListSelection();
|
void onJointListSelection();
|
||||||
|
|
||||||
void onLoDSourceCommit(S32 lod, bool refresh_ui);
|
void onLoDSourceCommit(S32 lod);
|
||||||
|
|
||||||
void modelUpdated(bool calculate_visible);
|
void modelUpdated(bool calculate_visible);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4984,6 +4984,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
||||||
items.push_back(std::string("Rename"));
|
items.push_back(std::string("Rename"));
|
||||||
items.push_back(std::string("thumbnail"));
|
items.push_back(std::string("thumbnail"));
|
||||||
|
|
||||||
|
addInventoryFavoritesMenuOptions(items);
|
||||||
addDeleteContextMenuOptions(items, disabled_items);
|
addDeleteContextMenuOptions(items, disabled_items);
|
||||||
// EXT-4030: disallow deletion of currently worn outfit
|
// EXT-4030: disallow deletion of currently worn outfit
|
||||||
const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
|
const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
|
||||||
|
|
@ -5009,6 +5010,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
||||||
EMyOutfitsSubfolderType in_my_outfits = myoutfit_object_subfolder_type(model, mUUID, outfits_id);
|
EMyOutfitsSubfolderType in_my_outfits = myoutfit_object_subfolder_type(model, mUUID, outfits_id);
|
||||||
if (in_my_outfits != MY_OUTFITS_NO)
|
if (in_my_outfits != MY_OUTFITS_NO)
|
||||||
{
|
{
|
||||||
|
// Either an outfit or a subfolder inside MY_OUTFITS
|
||||||
if (in_my_outfits == MY_OUTFITS_SUBFOLDER)
|
if (in_my_outfits == MY_OUTFITS_SUBFOLDER)
|
||||||
{
|
{
|
||||||
// Not inside an outfit, but inside 'my outfits'
|
// Not inside an outfit, but inside 'my outfits'
|
||||||
|
|
@ -5018,6 +5020,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
||||||
items.push_back(std::string("Rename"));
|
items.push_back(std::string("Rename"));
|
||||||
items.push_back(std::string("thumbnail"));
|
items.push_back(std::string("thumbnail"));
|
||||||
|
|
||||||
|
addInventoryFavoritesMenuOptions(items);
|
||||||
addDeleteContextMenuOptions(items, disabled_items);
|
addDeleteContextMenuOptions(items, disabled_items);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -5066,14 +5069,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
|
||||||
if (model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT) == mUUID)
|
if (model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT) == mUUID)
|
||||||
{
|
{
|
||||||
items.push_back(std::string("Copy outfit list to clipboard"));
|
items.push_back(std::string("Copy outfit list to clipboard"));
|
||||||
if (isFavorite())
|
addInventoryFavoritesMenuOptions(items);
|
||||||
{
|
|
||||||
items.push_back(std::string("Remove from Favorites"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
items.push_back(std::string("Add to Favorites"));
|
|
||||||
}
|
|
||||||
|
|
||||||
addOpenFolderMenuOptions(flags, items);
|
addOpenFolderMenuOptions(flags, items);
|
||||||
}
|
}
|
||||||
|
|
@ -5393,6 +5389,18 @@ void LLFolderBridge::addOpenFolderMenuOptions(U32 flags, menuentry_vec_t& items)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLFolderBridge::addInventoryFavoritesMenuOptions(menuentry_vec_t& items)
|
||||||
|
{
|
||||||
|
if (isFavorite())
|
||||||
|
{
|
||||||
|
items.push_back(std::string("Remove from Favorites"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
items.push_back(std::string("Add to Favorites"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool LLFolderBridge::hasChildren() const
|
bool LLFolderBridge::hasChildren() const
|
||||||
{
|
{
|
||||||
LLInventoryModel* model = getInventoryModel();
|
LLInventoryModel* model = getInventoryModel();
|
||||||
|
|
|
||||||
|
|
@ -372,6 +372,7 @@ protected:
|
||||||
void buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
|
void buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
|
||||||
void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
|
void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items);
|
||||||
void addOpenFolderMenuOptions(U32 flags, menuentry_vec_t& items);
|
void addOpenFolderMenuOptions(U32 flags, menuentry_vec_t& items);
|
||||||
|
void addInventoryFavoritesMenuOptions(menuentry_vec_t& items); // Inventory favorites, not toolbar favorites
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// Menu callbacks
|
// Menu callbacks
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@
|
||||||
|
|
||||||
// Increment this if the inventory contents change in a non-backwards-compatible way.
|
// Increment this if the inventory contents change in a non-backwards-compatible way.
|
||||||
// For viewer 2, the addition of link items makes a pre-viewer-2 cache incorrect.
|
// For viewer 2, the addition of link items makes a pre-viewer-2 cache incorrect.
|
||||||
const S32 LLInventoryModel::sCurrentInvCacheVersion = 4;
|
const S32 LLInventoryModel::sCurrentInvCacheVersion = 5;
|
||||||
bool LLInventoryModel::sFirstTimeInViewer2 = true;
|
bool LLInventoryModel::sFirstTimeInViewer2 = true;
|
||||||
|
|
||||||
S32 LLInventoryModel::sPendingSystemFolders = 0;
|
S32 LLInventoryModel::sPendingSystemFolders = 0;
|
||||||
|
|
@ -3664,7 +3664,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
|
||||||
}
|
}
|
||||||
LL_INFOS(LOG_INV) << "loading inventory from: (" << filename << ")" << LL_ENDL;
|
LL_INFOS(LOG_INV) << "loading inventory from: (" << filename << ")" << LL_ENDL;
|
||||||
|
|
||||||
llifstream file(filename.c_str());
|
llifstream file(filename.c_str(), std::ifstream::in | std::ifstream::binary);
|
||||||
|
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
{
|
{
|
||||||
|
|
@ -3673,55 +3673,66 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
|
||||||
}
|
}
|
||||||
|
|
||||||
is_cache_obsolete = true; // Obsolete until proven current
|
is_cache_obsolete = true; // Obsolete until proven current
|
||||||
|
U32 value_nbo = 0;
|
||||||
//U64 lines_count = 0U;
|
file.read((char*)&value_nbo, sizeof(U32));
|
||||||
std::string line;
|
if (file.fail())
|
||||||
LLPointer<LLSDParser> parser = new LLSDNotationParser();
|
|
||||||
while (std::getline(file, line))
|
|
||||||
{
|
{
|
||||||
LLSD s_item;
|
LL_WARNS(LOG_INV) << "Failed to read cache version. Unable to load inventory from: " << filename << LL_ENDL;
|
||||||
std::istringstream iss(line);
|
|
||||||
if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
|
|
||||||
{
|
|
||||||
LL_WARNS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (s_item.has("inv_cache_version"))
|
|
||||||
{
|
{
|
||||||
S32 version = s_item["inv_cache_version"].asInteger();
|
S32 version = (S32)ntohl(value_nbo);
|
||||||
if (version == sCurrentInvCacheVersion)
|
if (version == sCurrentInvCacheVersion)
|
||||||
{
|
{
|
||||||
// Cache is up to date
|
// Cache is up to date
|
||||||
is_cache_obsolete = false;
|
is_cache_obsolete = false;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LL_WARNS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL;
|
LL_WARNS(LOG_INV) << "Inventory cache is out of date" << LL_ENDL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (s_item.has("cat_id"))
|
|
||||||
{
|
|
||||||
if (is_cache_obsolete)
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
LLSD inventory;
|
||||||
|
if (!is_cache_obsolete)
|
||||||
|
{
|
||||||
|
LLPointer<LLSDParser> parser = new LLSDBinaryParser();
|
||||||
|
|
||||||
|
if (parser->parse(file, inventory, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
|
||||||
|
{
|
||||||
|
is_cache_obsolete = true;
|
||||||
|
LL_WARNS(LOG_INV) << "Parsing inventory cache failed" << LL_ENDL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_cache_obsolete)
|
||||||
|
{
|
||||||
|
const LLSD& llsd_cats = inventory["categories"];
|
||||||
|
if (llsd_cats.isArray())
|
||||||
|
{
|
||||||
|
LLSD::array_const_iterator iter = llsd_cats.beginArray();
|
||||||
|
LLSD::array_const_iterator end = llsd_cats.endArray();
|
||||||
|
for (; iter != end; ++iter)
|
||||||
|
{
|
||||||
LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
|
LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
|
||||||
if(inv_cat->importLLSD(s_item))
|
if (inv_cat->importLLSDMap(*iter))
|
||||||
{
|
{
|
||||||
categories.push_back(inv_cat);
|
categories.push_back(inv_cat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (s_item.has("item_id"))
|
}
|
||||||
{
|
|
||||||
if (is_cache_obsolete)
|
|
||||||
break;
|
|
||||||
|
|
||||||
LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
|
const LLSD& llsd_items = inventory["items"];
|
||||||
if( inv_item->fromLLSD(s_item) )
|
if (llsd_items.isArray())
|
||||||
{
|
{
|
||||||
if(inv_item->getUUID().isNull())
|
LLSD::array_const_iterator iter = llsd_items.beginArray();
|
||||||
|
LLSD::array_const_iterator end = llsd_items.endArray();
|
||||||
|
for (; iter != end; ++iter)
|
||||||
|
{
|
||||||
|
LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
|
||||||
|
if (inv_item->fromLLSD(*iter))
|
||||||
|
{
|
||||||
|
if (inv_item->getUUID().isNull())
|
||||||
{
|
{
|
||||||
LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: "
|
LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: "
|
||||||
<< inv_item->getName() << LL_ENDL;
|
<< inv_item->getName() << LL_ENDL;
|
||||||
|
|
@ -3738,15 +3749,16 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(brad) - figure out how to reenable this without breaking everything else
|
// TODO(brad) - figure out how to reenable this without breaking everything else
|
||||||
// static constexpr U64 BATCH_SIZE = 512U;
|
// static constexpr U64 BATCH_SIZE = 512U;
|
||||||
// if ((++lines_count % BATCH_SIZE) == 0)
|
// if ((++lines_count % BATCH_SIZE) == 0)
|
||||||
// {
|
// {
|
||||||
// // SL-19968 - make sure message system code gets a chance to run every so often
|
// // SL-19968 - make sure message system code gets a chance to run every so often
|
||||||
// pump_idle_startup_network();
|
// pump_idle_startup_network();
|
||||||
// }
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
@ -3769,58 +3781,54 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
llofstream fileXML(filename.c_str());
|
llofstream fileSD(filename.c_str(), std::ios_base::out | std::ios_base::binary);
|
||||||
if (!fileXML.is_open())
|
if (!fileSD.is_open())
|
||||||
{
|
{
|
||||||
LL_WARNS(LOG_INV) << "Failed to open file. Unable to save inventory to: " << filename << LL_ENDL;
|
LL_WARNS(LOG_INV) << "Failed to open file. Unable to save inventory to: " << filename << LL_ENDL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
U32 value_nbo = htonl(sCurrentInvCacheVersion);
|
||||||
LLSD cache_ver;
|
fileSD.write((const char*)(&value_nbo), sizeof(U32));
|
||||||
cache_ver["inv_cache_version"] = sCurrentInvCacheVersion;
|
if (fileSD.fail())
|
||||||
|
|
||||||
if (fileXML.fail())
|
|
||||||
{
|
{
|
||||||
LL_WARNS(LOG_INV) << "Failed to write cache version to file. Unable to save inventory to: " << filename << LL_ENDL;
|
LL_WARNS(LOG_INV) << "Failed to write cache. Unable to save inventory to: " << filename << LL_ENDL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl;
|
LLSD inventory;
|
||||||
|
inventory["categories"] = LLSD::emptyArray();
|
||||||
|
LLSD& cat_array = inventory["categories"];
|
||||||
|
|
||||||
S32 cat_count = 0;
|
S32 cat_count = 0;
|
||||||
for (auto& cat : categories)
|
for (auto& cat : categories)
|
||||||
{
|
{
|
||||||
if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
|
if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN)
|
||||||
{
|
{
|
||||||
LLSD sd = LLSD::emptyMap();
|
LLSD sd;
|
||||||
cat->exportLLSD(sd);
|
cat->exportLLSD(sd);
|
||||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
|
cat_array.append(sd);
|
||||||
cat_count++;
|
cat_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileXML.fail())
|
|
||||||
{
|
|
||||||
LL_WARNS(LOG_INV) << "Failed to write a folder to file. Unable to save inventory to: " << filename << LL_ENDL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inventory["items"] = LLSD::emptyArray();
|
||||||
|
LLSD& item_array = inventory["items"];
|
||||||
auto it_count = items.size();
|
auto it_count = items.size();
|
||||||
for (auto& item : items)
|
for (auto& item : items)
|
||||||
{
|
{
|
||||||
LLSD sd = LLSD::emptyMap();
|
LLSD sd;
|
||||||
item->asLLSD(sd);
|
item->asLLSD(sd);
|
||||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
|
item_array.append(sd);
|
||||||
|
}
|
||||||
if (fileXML.fail())
|
fileSD << LLSDOStreamer<LLSDBinaryFormatter>(inventory) << std::endl;
|
||||||
|
if (fileSD.fail())
|
||||||
{
|
{
|
||||||
LL_WARNS(LOG_INV) << "Failed to write an item to file. Unable to save inventory to: " << filename << LL_ENDL;
|
LL_WARNS(LOG_INV) << "Failed to write cache. Unable to save inventory to: " << filename << LL_ENDL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
fileSD.flush();
|
||||||
fileXML.flush();
|
|
||||||
|
|
||||||
fileXML.close();
|
fileSD.close();
|
||||||
|
|
||||||
LL_INFOS(LOG_INV) << "Inventory saved: " << (S32)cat_count << " categories, " << (S32)it_count << " items." << LL_ENDL;
|
LL_INFOS(LOG_INV) << "Inventory saved: " << (S32)cat_count << " categories, " << (S32)it_count << " items." << LL_ENDL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@
|
||||||
#include "lllogchat.h"
|
#include "lllogchat.h"
|
||||||
#include "llregex.h"
|
#include "llregex.h"
|
||||||
#include "lltrans.h"
|
#include "lltrans.h"
|
||||||
|
#include "llurlaction.h"
|
||||||
|
#include "llurlentry.h"
|
||||||
#include "llviewercontrol.h"
|
#include "llviewercontrol.h"
|
||||||
|
|
||||||
#include "lldiriterator.h"
|
#include "lldiriterator.h"
|
||||||
|
|
@ -445,13 +447,29 @@ void LLLogChat::saveHistory(const std::string& filename,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string altered_line = line;
|
||||||
|
|
||||||
|
// avoid costly regex calls
|
||||||
|
if (line.find("/mention") != std::string::npos)
|
||||||
|
{
|
||||||
|
static const boost::regex mention_regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/mention", boost::regex::perl | boost::regex::icase);
|
||||||
|
|
||||||
|
// replace mention URL with [@username](URL)
|
||||||
|
altered_line = boost::regex_replace(line, mention_regex, [](const boost::smatch& match) -> std::string
|
||||||
|
{
|
||||||
|
std::string url = match[0].str();
|
||||||
|
std::string username = LLUrlAction::getURLLabel(url);
|
||||||
|
return "[" + username + "](" + url + ")";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
LLSD item;
|
LLSD item;
|
||||||
|
|
||||||
if (gSavedPerAccountSettings.getBOOL("LogTimestamp"))
|
if (gSavedPerAccountSettings.getBOOL("LogTimestamp"))
|
||||||
item["time"] = LLLogChat::timestamp2LogString(0, gSavedPerAccountSettings.getBOOL("LogTimestampDate"));
|
item["time"] = LLLogChat::timestamp2LogString(0, gSavedPerAccountSettings.getBOOL("LogTimestampDate"));
|
||||||
|
|
||||||
item["from_id"] = from_id;
|
item["from_id"] = from_id;
|
||||||
item["message"] = line;
|
item["message"] = altered_line;
|
||||||
|
|
||||||
//adding "Second Life:" for all system messages to make chat log history parsing more reliable
|
//adding "Second Life:" for all system messages to make chat log history parsing more reliable
|
||||||
if (from.empty() && from_id.isNull())
|
if (from.empty() && from_id.isNull())
|
||||||
|
|
@ -563,6 +581,19 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
|
||||||
|
|
||||||
std::string line(remove_utf8_bom(buffer));
|
std::string line(remove_utf8_bom(buffer));
|
||||||
|
|
||||||
|
|
||||||
|
// fast heuristic test for a mention URL in a string
|
||||||
|
// this is used to avoid costly regex calls
|
||||||
|
if (line.find("/mention)") != std::string::npos)
|
||||||
|
{
|
||||||
|
// restore original mention URL from [@username](URL) format
|
||||||
|
static const boost::regex altered_mention_regex("\\[@([^\\]]+)\\]\\((" APP_HEADER_REGEX "/agent/[\\da-f-]+/mention)\\)",
|
||||||
|
boost::regex::perl | boost::regex::icase);
|
||||||
|
|
||||||
|
// $2 captures the URL part
|
||||||
|
line = boost::regex_replace(line, altered_mention_regex, "$2");
|
||||||
|
}
|
||||||
|
|
||||||
//updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
|
//updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message
|
||||||
if (' ' == line[0])
|
if (' ' == line[0])
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2395,6 +2395,7 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
|
||||||
{
|
{
|
||||||
// Restore base material
|
// Restore base material
|
||||||
LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te];
|
LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te];
|
||||||
|
LLUUID old_asset_id = objectp->getRenderMaterialID(te);
|
||||||
|
|
||||||
// Update material locally
|
// Update material locally
|
||||||
objectp->setRenderMaterialID(te, asset_id, false /*wait for LLGLTFMaterialList update*/);
|
objectp->setRenderMaterialID(te, asset_id, false /*wait for LLGLTFMaterialList update*/);
|
||||||
|
|
@ -2405,18 +2406,29 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
|
||||||
objectp->setTEGLTFMaterialOverride(te, material);
|
objectp->setTEGLTFMaterialOverride(te, material);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue update to server
|
if (asset_id.isNull() || !material)
|
||||||
if (asset_id.notNull() && material)
|
|
||||||
{
|
|
||||||
// Restore overrides and base material
|
|
||||||
LLGLTFMaterialList::queueApply(objectp, te, asset_id, material);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
//blank override out
|
//blank override out
|
||||||
LLGLTFMaterialList::queueApply(objectp, te, asset_id);
|
LLGLTFMaterialList::queueApply(objectp, te, asset_id);
|
||||||
}
|
}
|
||||||
|
if (old_asset_id != asset_id)
|
||||||
|
{
|
||||||
|
// Restore overrides and base material
|
||||||
|
// Note: might not work reliably if asset is already there, might
|
||||||
|
// have a server sided problem where servers applies override
|
||||||
|
// first then resets it by adding asset, in which case need
|
||||||
|
// to create a server ticket and chain asset then override
|
||||||
|
// application.
|
||||||
|
LLGLTFMaterialList::queueApply(objectp, te, asset_id, material);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Enqueue override update to server
|
||||||
|
// Note: this is suboptimal, better to send asset id as well
|
||||||
|
// but there seems to be a server problem with queueApply
|
||||||
|
// that ignores override in some cases
|
||||||
|
LLGLTFMaterialList::queueModify(objectp, te, material);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1139,28 +1139,33 @@ void set_texture_to_material(LLViewerObject* hit_obj,
|
||||||
case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR:
|
case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR:
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
material->setBaseColorId(asset_id);
|
material->setBaseColorId(asset_id, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS:
|
case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS:
|
||||||
{
|
{
|
||||||
material->setOcclusionRoughnessMetallicId(asset_id);
|
material->setOcclusionRoughnessMetallicId(asset_id, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE:
|
case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE:
|
||||||
{
|
{
|
||||||
material->setEmissiveId(asset_id);
|
material->setEmissiveId(asset_id, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL:
|
case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL:
|
||||||
{
|
{
|
||||||
material->setNormalId(asset_id);
|
material->setNormalId(asset_id, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Update viewer side, needed for updating mSavedGLTFOverrideMaterials.
|
||||||
|
// Also for parity, we are immediately setting textures and materials,
|
||||||
|
// so we should immediate set overrides to.
|
||||||
|
hit_obj->setTEGLTFMaterialOverride(hit_face, material);
|
||||||
|
// update server
|
||||||
LLGLTFMaterialList::queueModify(hit_obj, hit_face, material);
|
LLGLTFMaterialList::queueModify(hit_obj, hit_face, material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -851,18 +851,23 @@ void LLViewerInventoryCategory::exportLLSD(LLSD & cat_data) const
|
||||||
cat_data[INV_VERSION] = mVersion;
|
cat_data[INV_VERSION] = mVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLViewerInventoryCategory::importLLSD(const LLSD& cat_data)
|
bool LLViewerInventoryCategory::importLLSD(const std::string& label, const LLSD& value)
|
||||||
{
|
{
|
||||||
LLInventoryCategory::importLLSD(cat_data);
|
if (LLInventoryCategory::importLLSD(label, value))
|
||||||
if (cat_data.has(INV_OWNER_ID))
|
|
||||||
{
|
{
|
||||||
mOwnerID = cat_data[INV_OWNER_ID].asUUID();
|
|
||||||
}
|
|
||||||
if (cat_data.has(INV_VERSION))
|
|
||||||
{
|
|
||||||
setVersion(cat_data[INV_VERSION].asInteger());
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
else if (label == INV_OWNER_ID)
|
||||||
|
{
|
||||||
|
mOwnerID = value.asUUID();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (label == INV_VERSION)
|
||||||
|
{
|
||||||
|
setVersion(value.asInteger());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLViewerInventoryCategory::acceptItem(LLInventoryItem* inv_item)
|
bool LLViewerInventoryCategory::acceptItem(LLInventoryItem* inv_item)
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ public:
|
||||||
S32 getViewerDescendentCount() const;
|
S32 getViewerDescendentCount() const;
|
||||||
|
|
||||||
virtual void exportLLSD(LLSD &sd) const;
|
virtual void exportLLSD(LLSD &sd) const;
|
||||||
virtual bool importLLSD(const LLSD& cat_data);
|
virtual bool importLLSD(const std::string& label, const LLSD& value);
|
||||||
|
|
||||||
void determineFolderType();
|
void determineFolderType();
|
||||||
void changeType(LLFolderType::EType new_folder_type);
|
void changeType(LLFolderType::EType new_folder_type);
|
||||||
|
|
|
||||||
|
|
@ -7339,6 +7339,7 @@ const LLUUID& LLVOAvatar::getID() const
|
||||||
// getJoint()
|
// getJoint()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// RN: avatar joints are multi-rooted to include screen-based attachments
|
// RN: avatar joints are multi-rooted to include screen-based attachments
|
||||||
|
// virtual
|
||||||
LLJoint* LLVOAvatar::getJoint(std::string_view name)
|
LLJoint* LLVOAvatar::getJoint(std::string_view name)
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue