// TODO: Sort the legacy and non-legacy together?
void LLPreviewGesture::addAnimations()
{
	LLComboBox* combo = mAnimationCombo;

	combo->removeall();
	
	std::string none_text = getString("none_text");

	combo->add(none_text, LLUUID::null);

	// Add all the default (legacy) animations
	S32 i;
	for (i = 0; i < gUserAnimStatesCount; ++i)
	{
		// Use the user-readable name
		std::string label = LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName );
		const LLUUID& id = gUserAnimStates[i].mID;
		combo->add(label, id);
	}

	// Get all inventory items that are animations
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLIsTypeWithPermissions is_copyable_animation(LLAssetType::AT_ANIMATION,
													PERM_ITEM_UNRESTRICTED,
													gAgent.getID(),
													gAgent.getGroupID());
	gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									is_copyable_animation);

	// Copy into something we can sort
	std::vector<LLInventoryItem*> animations;

	S32 count = items.count();
	for(i = 0; i < count; ++i)
	{
		animations.push_back( items.get(i) );
	}

	// Do the sort
	std::sort(animations.begin(), animations.end(), SortItemPtrsByName());

	// And load up the combobox
	std::vector<LLInventoryItem*>::iterator it;
	for (it = animations.begin(); it != animations.end(); ++it)
	{
		LLInventoryItem* item = *it;

		combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM);
	}
}
bool FSExportPermsCheck::canExportAsset(LLUUID asset_id, std::string* name, std::string* description)
{
	bool exportable = false;
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLAssetIDMatches asset_id_matches(asset_id);
	gInventory.collectDescendentsIf(LLUUID::null,
									cats,
									items,
									LLInventoryModel::INCLUDE_TRASH,
									asset_id_matches);
	
	if (items.size())
	{
		// use the name of the first match
		(*name) = items[0]->getName();
		(*description) = items[0]->getDescription();
		
		for (S32 i = 0; i < items.size(); ++i)
		{
			if (!exportable)
			{
				LLPermissions perms = items[i]->getPermissions();
#ifdef OPENSIM
				if (LLGridManager::getInstance()->isInOpenSim())
				{
					switch (LFSimFeatureHandler::instance().exportPolicy())
					{
						case EXPORT_ALLOWED:
							exportable = (perms.getMaskOwner() & PERM_EXPORT) == PERM_EXPORT;
							break;
						/// TODO: Once enough grids adopt a version supporting exports, get consensus
						/// on whether we should allow full perm exports anymore.
						case EXPORT_UNDEFINED:
							exportable = (perms.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED;
							break;
						case EXPORT_DENIED:
						default:
							exportable = perms.getCreator() == gAgentID;
							break;
					}
				}
#endif
				if (LLGridManager::getInstance()->isInSecondLife() && (perms.getCreator() == gAgentID))
				{
					exportable = true;
				}
			}
		}
	}
	
	return exportable;
}
const LLUUID& JCLSLBridge::findInventoryByName(const std::string& object_name)
{
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	ObjectBNameMatches objectnamematches(object_name);
	gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),cats,items,FALSE,objectnamematches);

	if (items.count())
	{
		return items[0]->getUUID();
	}
	return LLUUID::null;
}
bool is_asset_exportable(const LLUUID& asset_id)
{
	if (asset_id.isNull()) return true; // Don't permission-check null textures
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLAssetIDMatches asset_id_matches(asset_id);
	gInventory.collectDescendentsIf(LLUUID::null, cats, items, true, asset_id_matches, false);

	for (int i = 0; i < items.count(); ++i)
	{
		if (perms_allow_export(items[i]->getPermissions())) return true;
	}
	return false;
}
Beispiel #5
0
const LLUUID& LLFloaterAO::getAssetIDByName(const std::string& name)
{
	if (name.empty()) return LLUUID::null;

	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	ObjectNameMatches objectnamematches(name);
	gInventory.collectDescendentsIf(LLUUID::null,cats,items,FALSE,objectnamematches);

	if (items.count())
	{
		return items[0]->getAssetUUID();
	}
	return LLUUID::null;
};
// static
bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, const LLSD& response)
{
	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
	LLInventoryCategory* cat = NULL;
	bool give_successful = true;
	switch(option)
	{
	case 0:  // "Yes"
		cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
		if (cat)
		{
			give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
				cat);
			LLViewerInventoryCategory::cat_array_t cats;
			LLViewerInventoryItem::item_array_t items;
			LLUncopyableItems remove;
			gInventory.collectDescendentsIf (cat->getUUID(),
				cats,
				items,
				LLInventoryModel::EXCLUDE_TRASH,
				remove);
			S32 count = items.count();
			for(S32 i = 0; i < count; ++i)
			{
				gInventory.deleteObject(items.get(i)->getUUID());
			}
			gInventory.notifyObservers();

			if (give_successful && notification["payload"]["success_notification"].isDefined())
			{
				LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
			}
		}
		else
		{
			LLNotificationsUtil::add("CannotGiveCategory");
			give_successful = false;
		}
		break;

	default: // no, cancel, whatever, who cares, not yes.
		LLNotificationsUtil::add("TransactionCancelled");
		give_successful = false;
		break;
	}
	return give_successful;
}
Beispiel #7
0
void findInventoryInFolder(const std::string& ifolder,std::vector<std::string>& rcats,std::vector<LLUUID>& ritems)
{
    LLUUID folder = gInventory.findCategoryByName(ifolder);
    LLViewerInventoryCategory::cat_array_t cats;
    LLViewerInventoryItem::item_array_t items;
    //ObjectContentNameMatches objectnamematches(ifolder);
    gInventory.collectDescendents(folder,cats,items,FALSE);//,objectnamematches);

    for(int i = 0; i<cats.count(); ++i)
    {
        rcats.push_back(((LLViewerInventoryCategory *)cats.get(i))->getName());
    }
    for(int i = 0; i<items.count(); ++i)
    {
        ritems.push_back(((LLViewerInventoryItem *)items.get(i))->getUUID());
    }
}
// So far, only Second Life forces TPVs to verify the creator for textures...
// which sucks, because there is no other way to check for the texture
// permissions or creator than to try and find the asset(s) corresponding to
// the texture in the inventory and check the permissions/creator on the said
// asset(s), meaning that if you created the texture and subsequently deleted
// it from your inventory, you will not be able to export it any more !!!
// The "must be creator" stuff also goes against the usage in Linden Lab's own
// official viewers, since those allow you to save full perm textures (such as
// the textures in the Library), whoever is the actual creator... Go figure !
LLUUID LLObjectBackup::validateTextureID(LLUUID asset_id)
{
	if (!gHippoGridManager->getConnectedGrid()->isSecondLife())
	{
		// If we are not in Second Life, don't bother.
		return asset_id;
	}
	LLUUID texture = LL_TEXTURE_PLYWOOD;
	if (asset_id == texture ||
		asset_id == LL_TEXTURE_BLANK ||
		asset_id == LL_TEXTURE_INVISIBLE ||
		asset_id == LL_TEXTURE_TRANSPARENT ||
		asset_id == LL_TEXTURE_MEDIA)
	{
		// Allow to export a few default SL textures.
		return asset_id;
	}
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLAssetIDMatches asset_id_matches(asset_id);
	gInventory.collectDescendentsIf(LLUUID::null,
							cats,
							items,
							LLInventoryModel::INCLUDE_TRASH,
							asset_id_matches);

	if (items.count())
	{
		for (S32 i = 0; i < items.count(); i++)
		{
			const LLPermissions item_permissions = items[i]->getPermissions();
			if (validatePerms(&item_permissions))
			{
				texture = asset_id;
			}
		}
	}

	if (texture != asset_id)
	{
		mNonExportedTextures |= TEXTURE_BAD_PERM;
	}

	return texture;
}
void LLPreviewGesture::addSounds()
{
	LLComboBox* combo = mSoundCombo;
	combo->removeall();
	
	std::string none_text = getString("none_text");

	combo->add(none_text, LLUUID::null);

	// Get all inventory items that are sounds
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLIsTypeWithPermissions is_copyable_sound(LLAssetType::AT_SOUND,
													PERM_ITEM_UNRESTRICTED,
													gAgent.getID(),
													gAgent.getGroupID());
	gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									is_copyable_sound);

	// Copy sounds into something we can sort
	std::vector<LLInventoryItem*> sounds;

	S32 i;
	S32 count = items.count();
	for(i = 0; i < count; ++i)
	{
		sounds.push_back( items.get(i) );
	}

	// Do the sort
	std::sort(sounds.begin(), sounds.end(), SortItemPtrsByName());

	// And load up the combobox
	std::vector<LLInventoryItem*>::iterator it;
	for (it = sounds.begin(); it != sounds.end(); ++it)
	{
		LLInventoryItem* item = *it;

		combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM);
	}
}
Beispiel #10
0
void LLFloaterAO::addAnimations()
{
	mAnimListCombo->removeall();
	
	std::string none_text = getString("none_text");
	mAnimListCombo->add(none_text, LLUUID::null);

	// Add all the default (legacy) animations
	S32 i;

	// Get all inventory items that are animations
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLIsTypeWithPermissions is_copyable_animation(LLAssetType::AT_ANIMATION,
													PERM_NONE,
													gAgent.getID(),
													gAgent.getGroupID());
	gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									is_copyable_animation);

	// Copy into something we can sort
	std::vector<LLInventoryItem*> animations;

	S32 count = items.count();
	for(i = 0; i < count; ++i)
	{
		animations.push_back( items.get(i) );
	}

	// Do the sort
	std::sort(animations.begin(), animations.end(), SortItemPtrsByName());

	// And load up the combobox
	std::vector<LLInventoryItem*>::iterator it;
	for (it = animations.begin(); it != animations.end(); ++it)
	{
		LLInventoryItem* item = *it;
		mAnimListCombo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM);
	}
}
//static
bool LLObjectBackup::validateTexturePerms(const LLUUID& asset_id)
{
	if (LFSimFeatureHandler::instance().exportPolicy() == ep_full_perm)
	{
		// If we are not in Second Life and we don't have export-permission
		// support, don't bother and unconditionally accept the texture export
		// (legacy behaviour).
		return true;
	}

	if (asset_id == LL_TEXTURE_PLYWOOD ||
		asset_id == LL_TEXTURE_BLANK ||
		asset_id == LL_TEXTURE_INVISIBLE ||
		asset_id == LL_TEXTURE_TRANSPARENT ||
		asset_id == LL_TEXTURE_MEDIA)
	{
		// Allow to export a few default SL textures.
		return true;
	}

	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLAssetIDMatches asset_id_matches(asset_id);
	gInventory.collectDescendentsIf(LLUUID::null, cats, items,
							LLInventoryModel::INCLUDE_TRASH,
							asset_id_matches);
	S32 count = items.size();
	if (count > 0)
	{
		for (S32 i = 0; i < count; ++i)
		{
			const LLPermissions item_permissions = items[i]->getPermissions();
			if (validatePerms(&item_permissions))
			{
				return true;
			}
		}
	}

	return false;
}
void FSLSLBridge::detachOtherBridges()
{
	LLUUID catID = findFSCategory();
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;

	LLViewerInventoryItem* fsBridge = findInvObject(mCurrentFullName, catID, LLAssetType::AT_OBJECT);

	//detach everything except current valid bridge - if any
	gInventory.collectDescendents(catID,cats,items,FALSE);

	for (S32 iIndex = 0; iIndex < items.count(); iIndex++)
	{
		const LLViewerInventoryItem* itemp = items.get(iIndex);
		if (get_is_item_worn(itemp->getUUID()) &&
			((fsBridge == NULL) || (itemp->getUUID() != fsBridge->getUUID())))
		{
			LLVOAvatarSelf::detachAttachmentIntoInventory(itemp->getUUID());
		}
	}
}
void FSLSLBridge :: cleanUpBridgeFolder()
{
	llinfos << "Cleaning leftover scripts and bridges..." << llendl;
	
	LLUUID catID = findFSCategory();
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;

	//find all bridge and script duplicates and delete them
	NameCollectFunctor namefunctor(mCurrentFullName);
	gInventory.collectDescendentsIf(catID,cats,items,FALSE,namefunctor);

	for (S32 iIndex = 0; iIndex < items.count(); iIndex++)
	{
		const LLViewerInventoryItem* itemp = items.get(iIndex);
		if (!itemp->getIsLinkType()  && (itemp->getUUID() != mpBridge->getUUID()))
		{
			gInventory.purgeObject(itemp->getUUID());
		}
	}
	gInventory.notifyObservers();
}
Beispiel #14
0
const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only)
{
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLAssetIDMatches asset_id_matches(asset_id);
	gInventory.collectDescendentsIf(LLUUID::null,
							cats,
							items,
							LLInventoryModel::INCLUDE_TRASH,
							asset_id_matches);

	if (items.count())
	{
		// search for copyable version first
		for (S32 i = 0; i < items.count(); i++)
		{
			LLInventoryItem* itemp = items[i];
			LLPermissions item_permissions = itemp->getPermissions();
			if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID()))
			{
				return itemp->getUUID();
			}
		}
		// otherwise just return first instance, unless copyable requested
		if (copyable_only)
		{
			return LLUUID::null;
		}
		else
		{
			return items[0]->getUUID();
		}
	}

	return LLUUID::null;
}
Beispiel #15
0
// So far, only Second Life forces TPVs to verify the creator for textures...
// which sucks, because there is no other way to check for the texture
// permissions or creator than to try and find the asset(s) corresponding to
// the texture in the inventory and check the permissions/creator on the said
// asset(s), meaning that if you created the texture and subsequently deleted
// it from your inventory, you will not be able to export it any more !!!
// The "must be creator" stuff also goes against the usage in Linden Lab's own
// official viewers, since those allow you to save full perm textures (such as
// the textures in the Library), whoever is the actual creator... Go figure !
LLUUID LLObjectBackup::validateTextureID(LLUUID asset_id)
{
	if (gHippoGridManager->getConnectedGrid()->getPlatform() != HippoGridInfo::PLATFORM_SECONDLIFE)
	{
		// If we are not in Second Life, don't bother.
		return asset_id;
	}
	LLUUID texture = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLAssetIDMatches asset_id_matches(asset_id);
	gInventory.collectDescendentsIf(LLUUID::null,
							cats,
							items,
							LLInventoryModel::INCLUDE_TRASH,
							asset_id_matches);

	if (items.count())
	{
		for (S32 i = 0; i < items.count(); i++)
		{
			const LLPermissions item_permissions = items[i]->getPermissions();
			if (validatePerms(&item_permissions))
			{
				texture = asset_id;
			}
		}
	}

	if (texture != asset_id)
	{
		mNonExportedTextures |= TEXTURE_BAD_PERM;
	}

	return texture;
}
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
{
 	LLInventoryObject const* objectp = gInventory.getObject(id);
	LLUUID root_id = mFolderRoot.get()->getListener()->getUUID();
 	LLFolderViewFolder* parent_folder = NULL;
	LLFolderViewItem* itemp = NULL;
	
 	if (id == root_id)
 	{
		parent_folder = mFolderRoot.get();
 	}
 	else if (objectp)
 	{
 		const LLUUID &parent_id = objectp->getParentUUID();
		parent_folder = (LLFolderViewFolder*)mFolderRoot.get()->getItemByID(parent_id);
  		
  		if (parent_folder)
  		{
  			if (objectp->getType() <= LLAssetType::AT_NONE ||
  				objectp->getType() >= LLAssetType::AT_COUNT)
  			{
  				llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
  						<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
  						<< llendl;
  				return NULL;
  			}
  		
  			if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
  				(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
			{
  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
													objectp->getType(),
													LLInventoryType::IT_CATEGORY,
													this,
													mFolderRoot.get(),
													objectp->getUUID());
  				if (new_listener)
  				{
					LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
					if (folderp)
					{
						folderp->setItemSortOrder(mFolderRoot.get()->getSortOrder());
					}
  					itemp = folderp;
  				}
  			}
  			else
  			{
  				// Build new view for item.
  				LLInventoryItem* item = (LLInventoryItem*)objectp;
  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
				item->getActualType(),
				item->getInventoryType(),
  																				this,
																				mFolderRoot.get(),
  																				item->getUUID(),
  																				item->getFlags());
 
  				if (new_listener)
  				{
					itemp = createFolderViewItem(new_listener);
  				}
  			}
 
  			if (itemp)
  			{
				itemp->addToFolder(parent_folder, mFolderRoot.get());
   			}
		}
	}

	// If this is a folder, add the children of the folder and recursively add any 
	// child folders.
	if (id.isNull()
		||	(objectp
			&& objectp->getType() == LLAssetType::AT_CATEGORY))
	{
		LLViewerInventoryCategory::cat_array_t* categories;
		LLViewerInventoryItem::item_array_t* items;
		mInventory->lockDirectDescendentArrays(id, categories, items);
		
		if(categories)
		{
			for (LLViewerInventoryCategory::cat_array_t::const_iterator cat_iter = categories->begin();
				 cat_iter != categories->end();
				 ++cat_iter)
			{
				const LLViewerInventoryCategory* cat = (*cat_iter);
				buildNewViews(cat->getUUID());
			}
		}
		
		if(items && parent_folder)
		{
			for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
				 item_iter != items->end();
				 ++item_iter)
			{
				const LLViewerInventoryItem* item = (*item_iter);
				buildNewViews(item->getUUID());
			}
		}
		mInventory->unlockDirectDescendentArrays(id);
	}
	
	return itemp;
}
void LLInventoryPanel::buildNewViews(const LLUUID& id)
{
	LLFolderViewItem* itemp = NULL;
	LLInventoryObject* objectp = gInventory.getObject(id);

	if (objectp)
	{		
		if (objectp->getType() <= LLAssetType::AT_NONE ||
			objectp->getType() >= LLAssetType::AT_COUNT)
		{
			llwarns << "LLInventoryPanel::buildNewViews called with objectp->mType == " 
				<< ((S32) objectp->getType())
				<< " (shouldn't happen)" << llendl;
		}
		else if (objectp->getType() == LLAssetType::AT_CATEGORY) // build new view for category
		{
			LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(),
													LLInventoryType::IT_CATEGORY,
													this,
													objectp->getUUID());

			if (new_listener)
			{
				LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(),
													new_listener->getIcon(),
													mFolders,
													new_listener);
				
				folderp->setItemSortOrder(mFolders->getSortOrder());
				itemp = folderp;
			}
		}
		else // build new view for item
		{
			LLInventoryItem* item = (LLInventoryItem*)objectp;
			LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(
				item->getType(),
				item->getInventoryType(),
				this,
				item->getUUID(),
				item->getFlags());
			if (new_listener)
			{
				itemp = new LLFolderViewItem(new_listener->getDisplayName(),
												new_listener->getIcon(),
												new_listener->getCreationDate(),
												mFolders,
												new_listener);
			}
		}

		LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolders->getItemByID(objectp->getParentUUID());

		if (itemp)
		{
			if (parent_folder)
			{
				itemp->addToFolder(parent_folder, mFolders);
			}
			else
			{
				llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl;
				delete itemp;
			}
		}
	}

	if ((id.isNull() ||
		(objectp && objectp->getType() == LLAssetType::AT_CATEGORY)))
	{
		LLViewerInventoryCategory::cat_array_t* categories;
		LLViewerInventoryItem::item_array_t* items;

		mInventory->lockDirectDescendentArrays(id, categories, items);
		if(categories)
		{
			S32 count = categories->count();
			for(S32 i = 0; i < count; ++i)
			{
				LLInventoryCategory* cat = categories->get(i);
				buildNewViews(cat->getUUID());
			}
		}
		if(items)
		{
			S32 count = items->count();
			for(S32 i = 0; i < count; ++i)
			{
				LLInventoryItem* item = items->get(i);
				buildNewViews(item->getUUID());
			}
		}
		mInventory->unlockDirectDescendentArrays(id);
	}
}
// static
bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
													const LLInventoryCategory* cat,
													const LLUUID& im_session_id)

{
	if (!cat)
	{
		return false;
	}
	llinfos << "LLGiveInventory::commitGiveInventoryCategory() - "
		<< cat->getUUID() << llendl;

	// add buddy to recent people list
//	LLRecentPeople::instance().add(to_agent);
// [RLVa:KB] - Checked: 2010-04-20 (RLVa-1.2.2a) | Added: RLVa-1.2.0f
	// Block the recent activity update if this was an in-world drop on an avatar (as opposed to a drop on an IM session or on a profile)
	if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) || (im_session_id.notNull()) || (!RlvUtil::isNearbyAgent(to_agent)) ||
		 (RlvUIEnabler::hasOpenProfile(to_agent)) )
	{
		LLRecentPeople::instance().add(to_agent);
	}
// [/RLVa:KB]

	// Test out how many items are being given.
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLGiveable giveable;
	gInventory.collectDescendentsIf (cat->getUUID(),
		cats,
		items,
		LLInventoryModel::EXCLUDE_TRASH,
		giveable);

	bool give_successful = true;
	// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
	// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
	// 66. I've cut it down a bit from there to give some pad.
	S32 count = items.count() + cats.count();
	if (count > MAX_ITEMS)
	{
		LLNotificationsUtil::add("TooManyItems");
		give_successful = false;
	}
	else if (count == 0)
	{
		LLNotificationsUtil::add("NoItems");
		give_successful = false;
	}
	else
	{
		std::string name;
		LLAgentUI::buildFullname(name);
		LLUUID transaction_id;
		transaction_id.generate();
		S32 bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1);
		U8* bucket = new U8[bucket_size];
		U8* pos = bucket;
		U8 type = (U8)cat->getType();
		memcpy(pos, &type, sizeof(U8));		/* Flawfinder: ignore */
		pos += sizeof(U8);
		memcpy(pos, &(cat->getUUID()), UUID_BYTES);		/* Flawfinder: ignore */
		pos += UUID_BYTES;
		S32 i;
		count = cats.count();
		for(i = 0; i < count; ++i)
		{
			memcpy(pos, &type, sizeof(U8));		/* Flawfinder: ignore */
			pos += sizeof(U8);
			memcpy(pos, &(cats.get(i)->getUUID()), UUID_BYTES);		/* Flawfinder: ignore */
			pos += UUID_BYTES;
		}
		count = items.count();
		for(i = 0; i < count; ++i)
		{
			type = (U8)items.get(i)->getType();
			memcpy(pos, &type, sizeof(U8));		/* Flawfinder: ignore */
			pos += sizeof(U8);
			memcpy(pos, &(items.get(i)->getUUID()), UUID_BYTES);		/* Flawfinder: ignore */
			pos += UUID_BYTES;
		}
		pack_instant_message(
			gMessageSystem,
			gAgent.getID(),
			FALSE,
			gAgent.getSessionID(),
			to_agent,
			name,
			cat->getName(),
			IM_ONLINE,
			IM_INVENTORY_OFFERED,
			transaction_id,
			0,
			LLUUID::null,
			gAgent.getPositionAgent(),
			NO_TIMESTAMP,
			bucket,
			bucket_size);
		gAgent.sendReliableMessage();
		delete[] bucket;

		// VEFFECT: giveInventoryCategory
		// <FS:Ansariel> Make the particle effect optional
		if (gSavedSettings.getBOOL("FSCreateGiveInventoryParticleEffect"))
		{
			LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
			effectp->setSourceObject(gAgentAvatarp);
			effectp->setTargetObject(gObjectList.findObject(to_agent));
			effectp->setDuration(LL_HUD_DUR_SHORT);
			effectp->setColor(LLColor4U(gAgent.getEffectColor()));
		}
		gFloaterTools->dirty();

		LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);

		logInventoryOffer(to_agent, im_session_id);
	}

	return give_successful;
}
void LLInventoryPanel::buildNewViews(const LLUUID& id)
{
	LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS);
	LLFolderViewItem* itemp = NULL;
	LLInventoryObject* objectp = gInventory.getObject(id);
	if (objectp)
	{
		const LLUUID &parent_id = objectp->getParentUUID();
		LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
		if (id == mStartFolderID)
		{
			parent_folder = mFolderRoot;
		}
		else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))
		{
			// This item exists outside the inventory's hierarchy, so don't add it.
			return;
		}
		
		if (objectp->getType() <= LLAssetType::AT_NONE ||
			objectp->getType() >= LLAssetType::AT_COUNT)
		{
			llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
					<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() 
					<< llendl;
			return;
		}
		
		if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
			(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
		{
			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
																			objectp->getType(),
																			LLInventoryType::IT_CATEGORY,
																			this,
																			mFolderRoot,
																			objectp->getUUID());
			if (new_listener)
			{
				LLFolderViewFolder::Params params;
				params.name = new_listener->getDisplayName();
				params.icon = new_listener->getIcon();
				params.icon_open = new_listener->getOpenIcon();
				if (mShowItemLinkOverlays) // if false, then links show up just like normal items
				{
					params.icon_overlay = LLUI::getUIImage("Inv_Link");
				}
				params.root = mFolderRoot;
				params.listener = new_listener;
				params.tool_tip = params.name;
				LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params);
				folderp->setItemSortOrder(mFolderRoot->getSortOrder());
				itemp = folderp;

				// Hide the root folder, so we can show the contents of a folder flat
				// but still have the parent folder present for listener-related operations.
				if (id == mStartFolderID)
				{
					folderp->setHidden(TRUE);
				}
				const LLViewerInventoryCategory *cat = dynamic_cast<LLViewerInventoryCategory *>(objectp);
				if (cat && getIsHiddenFolderType(cat->getPreferredType()))
				{
					folderp->setHidden(TRUE);
				}
			}
		}
		else 
		{
			// Build new view for item.
			LLInventoryItem* item = (LLInventoryItem*)objectp;
			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
																			item->getActualType(),
																			item->getInventoryType(),
																			this,
																			mFolderRoot,
																			item->getUUID(),
																			item->getFlags());

			if (new_listener)
			{
				LLFolderViewItem::Params params;
				params.name = new_listener->getDisplayName();
				params.icon = new_listener->getIcon();
				params.icon_open = new_listener->getOpenIcon();
				if (mShowItemLinkOverlays) // if false, then links show up just like normal items
				{
					params.icon_overlay = LLUI::getUIImage("Inv_Link");
				}
				params.creation_date = new_listener->getCreationDate();
				params.root = mFolderRoot;
				params.listener = new_listener;
				params.rect = LLRect (0, 0, 0, 0);
				params.tool_tip = params.name;
				itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
			}
		}

		if (itemp)
		{
			itemp->addToFolder(parent_folder, mFolderRoot);

			// Don't add children of hidden folders unless this is the panel's root folder.
			if (itemp->getHidden() && (id != mStartFolderID))
			{
				return;
			}
		}
	}

	// If this is a folder, add the children of the folder and recursively add any 
	// child folders.
	if ((id == mStartFolderID) ||
		(objectp && objectp->getType() == LLAssetType::AT_CATEGORY))
	{
		LLViewerInventoryCategory::cat_array_t* categories;
		LLViewerInventoryItem::item_array_t* items;
		mInventory->lockDirectDescendentArrays(id, categories, items);
		
		if(categories)
		{
			for (LLViewerInventoryCategory::cat_array_t::const_iterator cat_iter = categories->begin();
				 cat_iter != categories->end();
				 ++cat_iter)
			{
				const LLViewerInventoryCategory* cat = (*cat_iter);
				buildNewViews(cat->getUUID());
			}
		}
		
		if(items)
		{
			for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
				 item_iter != items->end();
				 ++item_iter)
			{
				const LLViewerInventoryItem* item = (*item_iter);
				buildNewViews(item->getUUID());
			}
		}
		mInventory->unlockDirectDescendentArrays(id);
	}
}
bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
											  const LLInventoryCategory* cat,
											  const LLUUID& im_session_id,
											  const std::string& notification_name)

{
	if (!cat)
	{
		return false;
	}
	LL_INFOS() << "LLGiveInventory::giveInventoryCategory() - "
		<< cat->getUUID() << LL_ENDL;

	if (!isAgentAvatarValid())
	{
		return false;
	}

	bool give_successful = true;
	// Test out how many items are being given.
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLGiveable giveable;
	gInventory.collectDescendentsIf(cat->getUUID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									giveable);
	S32 count = cats.size();
	bool complete = true;
	for(S32 i = 0; i < count; ++i)
	{
		if(!gInventory.isCategoryComplete(cats.at(i)->getUUID()))
		{
			complete = false;
			break;
		}
	}
	if(!complete)
	{
		LLNotificationsUtil::add("IncompleteInventory");
		give_successful = false;
	}
	count = items.size() + cats.size();
	if(count > MAX_ITEMS)
	{
		LLNotificationsUtil::add("TooManyItems");
		give_successful = false;
	}
	else if(count == 0)
	{
		LLNotificationsUtil::add("NoItems");
		give_successful = false;
	}
	else if (give_successful)
	{
		if(0 == giveable.countNoCopy())
		{
			give_successful = LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
		}
		else
		{
			LLSD args;
			args["COUNT"] = llformat("%d",giveable.countNoCopy());
			LLSD payload;
			payload["agent_id"] = to_agent;
			payload["folder_id"] = cat->getUUID();
			if (!notification_name.empty())
			{
				payload["success_notification"] = notification_name;
			}
			LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory);
			give_successful = false;
		}
	}

	return give_successful;
}
void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInventoryObject* objectp)
{
	LLFolderViewItem* itemp = NULL;

	if (objectp)
	{		
		if (objectp->getType() <= LLAssetType::AT_NONE ||
			objectp->getType() >= LLAssetType::AT_COUNT)
		{
			llwarns << "called with objectp->mType == " 
				<< ((S32) objectp->getType())
				<< " (shouldn't happen)" << llendl;
		}
		else if (objectp->getType() == LLAssetType::AT_CATEGORY) // build new view for category
		{
			LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(),
													LLInventoryType::IT_CATEGORY,
													panelp,
													objectp->getUUID());

			if (new_listener)
			{
				LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(),
													new_listener->getIcon(),
													panelp->getRootFolder(),
													new_listener);
				
				folderp->setItemSortOrder(panelp->getSortOrder());
				itemp = folderp;
			}
		}
		else // build new view for item
		{
			LLInventoryItem* item = (LLInventoryItem*)objectp;
			LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(
				item->getType(),
				item->getInventoryType(),
				panelp,
				item->getUUID(),
				item->getFlags());
			if (new_listener)
			{
				itemp = new LLFolderViewItem(new_listener->getDisplayName(),
												new_listener->getIcon(),
												new_listener->getCreationDate(),
												panelp->getRootFolder(),
												new_listener);
			}
		}

		LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)panelp->getRootFolder()->getItemByID(objectp->getParentUUID());

		if (itemp)
		{
			itemp->mDelayedDelete = TRUE;
			if (parent_folder)
			{
				itemp->addToFolder(parent_folder, panelp->getRootFolder());
			}
			else
			{
				llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl;
				delete itemp;
			}
		}
	}

	if (!objectp || (objectp && (objectp->getType() == LLAssetType::AT_CATEGORY)))
	{
		LLViewerInventoryCategory::cat_array_t* categories;
		LLViewerInventoryItem::item_array_t* items;

		panelp->getModel()->lockDirectDescendentArrays((objectp != NULL) ? objectp->getUUID() : LLUUID::null, categories, items);
		if(categories)
		{
			S32 count = categories->count();
			for(S32 i = 0; i < count; ++i)
			{
				LLInventoryCategory* cat = categories->get(i);
				addJob(panelp, cat);
			}
		}
		if(items)
		{
			S32 count = items->count();
			for(S32 i = 0; i < count; ++i)
			{
				LLInventoryItem* item = items->get(i);
				addJob(panelp, item);
			}
		}
		panelp->getModel()->unlockDirectDescendentArrays(objectp->getUUID());
	}
}
void LLGestureMgr::activateGestures(LLViewerInventoryItem::item_array_t& items)
{
	// Load up the assets
	S32 count = 0;
	LLViewerInventoryItem::item_array_t::const_iterator it;
	for (it = items.begin(); it != items.end(); ++it)
	{
		LLViewerInventoryItem* item = *it;

		if (isGestureActive(item->getUUID()))
		{
			continue;
		}
		else 
		{ // Make gesture active and persistent through login sessions.  -Aura 07-12-06
			activateGesture(item->getUUID());
		}

		count++;
	}

	mLoadingCount = count;
	mDeactivateSimilarNames.clear();

	for (it = items.begin(); it != items.end(); ++it)
	{
		LLViewerInventoryItem* item = *it;

		if (isGestureActive(item->getUUID()))
		{
			continue;
		}

		// Don't inform server, we'll do that in bulk
		const BOOL no_inform_server = FALSE;
		const BOOL deactivate_similar = TRUE;
		activateGestureWithAsset(item->getUUID(), item->getAssetUUID(),
								 no_inform_server,
								 deactivate_similar);
	}

	// Inform the database of this change
	LLMessageSystem* msg = gMessageSystem;

	BOOL start_message = TRUE;

	for (it = items.begin(); it != items.end(); ++it)
	{
		LLViewerInventoryItem* item = *it;

		if (isGestureActive(item->getUUID()))
		{
			continue;
		}

		if (start_message)
		{
			msg->newMessage("ActivateGestures");
			msg->nextBlock("AgentData");
			msg->addUUID("AgentID", gAgent.getID());
			msg->addUUID("SessionID", gAgent.getSessionID());
			msg->addU32("Flags", 0x0);
			start_message = FALSE;
		}
		
		msg->nextBlock("Data");
		msg->addUUID("ItemID", item->getUUID());
		msg->addUUID("AssetID", item->getAssetUUID());
		msg->addU32("GestureFlags", 0x0);

		if (msg->getCurrentSendTotal() > MTUBYTES)
		{
			gAgent.sendReliableMessage();
			start_message = TRUE;
		}
	}

	if (!start_message)
	{
		gAgent.sendReliableMessage();
	}
}
void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
											  const LLInventoryCategory* cat,
											  const LLUUID& im_session_id)

{
	if (!cat) return;
	llinfos << "LLGiveInventory::giveInventoryCategory() - "
		<< cat->getUUID() << llendl;

	if (!isAgentAvatarValid()) return;

	// Test out how many items are being given.
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLGiveable giveable;
	gInventory.collectDescendentsIf(cat->getUUID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									giveable);
	S32 count = cats.count();
	bool complete = true;
	for(S32 i = 0; i < count; ++i)
	{
		if(!gInventory.isCategoryComplete(cats.get(i)->getUUID()))
		{
			complete = false;
			break;
		}
	}
	if(!complete)
	{
		LLNotificationsUtil::add("IncompleteInventory");
		return;
	}
 	count = items.count() + cats.count();
 	if(count > MAX_ITEMS)
  	{
		LLNotificationsUtil::add("TooManyItems");
  		return;
  	}
 	else if(count == 0)
  	{
		LLNotificationsUtil::add("NoItems");
  		return;
  	}
	else
	{
		if(0 == giveable.countNoCopy())
		{
			LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
		}
		else 
		{
			LLSD args;
			args["COUNT"] = llformat("%d",giveable.countNoCopy());
			LLSD payload;
			payload["agent_id"] = to_agent;
			payload["folder_id"] = cat->getUUID();
			LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory);
		}
	}
}
// static
void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
													const LLInventoryCategory* cat,
													const LLUUID& im_session_id)

{
if(!cat) return;
	llinfos << "LLGiveInventory::commitGiveInventoryCategory() - "
			<< cat->getUUID() << llendl;

	// Test out how many items are being given.
	LLViewerInventoryCategory::cat_array_t cats;
	LLViewerInventoryItem::item_array_t items;
	LLGiveable giveable;
	gInventory.collectDescendentsIf(cat->getUUID(),
									cats,
									items,
									LLInventoryModel::EXCLUDE_TRASH,
									giveable);

	// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
	// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
	// 66. I've cut it down a bit from there to give some pad.
 	S32 count = items.count() + cats.count();
 	if(count > MAX_ITEMS)
  	{
		LLNotificationsUtil::add("TooManyItems");
  		return;
  	}
 	else if(count == 0)
  	{
		LLNotificationsUtil::add("NoItems");
  		return;
  	}
	else
	{
		std::string name;
		LLAgentUI::buildFullname(name);
		LLUUID transaction_id;
		transaction_id.generate();
		S32 bucket_size = (sizeof(U8) + UUID_BYTES) * (count + 1);
		U8* bucket = new U8[bucket_size];
		U8* pos = bucket;
		U8 type = (U8)cat->getType();
		memcpy(pos, &type, sizeof(U8));		/* Flawfinder: ignore */
		pos += sizeof(U8);
		memcpy(pos, &(cat->getUUID()), UUID_BYTES);		/* Flawfinder: ignore */
		pos += UUID_BYTES;
		S32 i;
		count = cats.count();
		for(i = 0; i < count; ++i)
		{
			memcpy(pos, &type, sizeof(U8));		/* Flawfinder: ignore */
			pos += sizeof(U8);
			memcpy(pos, &(cats.get(i)->getUUID()), UUID_BYTES);		/* Flawfinder: ignore */
			pos += UUID_BYTES;
		}
		count = items.count();
		for(i = 0; i < count; ++i)
		{
			type = (U8)items.get(i)->getType();
			memcpy(pos, &type, sizeof(U8));		/* Flawfinder: ignore */
			pos += sizeof(U8);
			memcpy(pos, &(items.get(i)->getUUID()), UUID_BYTES);		/* Flawfinder: ignore */
			pos += UUID_BYTES;
		}
		pack_instant_message(
			gMessageSystem,
			gAgent.getID(),
			FALSE,
			gAgent.getSessionID(),
			to_agent,
			name,
			cat->getName(),
			IM_ONLINE,
			IM_INVENTORY_OFFERED,
			transaction_id,
			0,
			LLUUID::null,
			gAgent.getPositionAgent(),
			NO_TIMESTAMP,
			bucket,
			bucket_size);
		gAgent.sendReliableMessage();
		delete[] bucket;
		// <edit>
 		if (gSavedSettings.getBOOL("BroadcastViewerEffects"))
		{
 			// </edit>
			// VEFFECT: giveInventoryCategory
			LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
			effectp->setSourceObject(gAgentAvatarp);
			effectp->setTargetObject(gObjectList.findObject(to_agent));
			effectp->setDuration(LL_HUD_DUR_SHORT);
			effectp->setColor(LLColor4U(gAgent.getEffectColor()));
			// <edit>
		}
		// </edit>
		gFloaterTools->dirty();

		LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);

		logInventoryOffer(to_agent, im_session_id);
	}
}
bool FSExportPermsCheck::canExportNode(LLSelectNode* node, bool dae)
{
	if (!node)
	{
		LL_WARNS("export") << "No node, bailing!" << LL_ENDL;
		return false;
	}
	bool exportable = false;
	
	LLViewerObject* object = node->getObject();
	if (LLGridManager::getInstance()->isInSecondLife())
	{
		LLUUID creator(node->mPermissions->getCreator());
		exportable = (object->permYouOwner() && gAgentID == creator);
		if (!exportable)
		{
			// Megaprim check
			F32 max_object_size = LLWorld::getInstance()->getRegionMaxPrimScale();
			LLVector3 vec = object->getScale();
			if (vec.mV[VX] > max_object_size || vec.mV[VY] > max_object_size || vec.mV[VZ] > max_object_size)
				exportable = (creator == LLUUID("7ffd02d0-12f4-48b4-9640-695708fd4ae4") // Zwagoth Klaar
							  || creator == gAgentID);
		}
	}
#ifdef OPENSIM
	else if (LLGridManager::getInstance()->isInOpenSim())
	{
		switch (LFSimFeatureHandler::instance().exportPolicy())
		{
			case EXPORT_ALLOWED:
			{
				exportable = node->mPermissions->allowExportBy(gAgent.getID());
				break;
			}
			/// TODO: Once enough grids adopt a version supporting exports, get consensus
			/// on whether we should allow full perm exports anymore.
			case EXPORT_UNDEFINED:
			{
				exportable = (object->permYouOwner() && object->permModify() && object->permCopy() && object->permTransfer());
				break;
			}
			case EXPORT_DENIED:
			default:
				exportable = (object->permYouOwner() && gAgentID == node->mPermissions->getCreator());
		}
	}
#endif // OPENSIM
	// We've got perms on the object itself, let's check for sculptmaps and meshes!
	if (exportable)
	{
		LLVOVolume *volobjp = NULL;
		if (object->getPCode() == LL_PCODE_VOLUME)
		{
			volobjp = (LLVOVolume *)object;
		}
		if (volobjp && volobjp->isSculpted())
		{
			const LLSculptParams *sculpt_params = (const LLSculptParams *)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			if (LLGridManager::getInstance()->isInSecondLife())
			{
				if(volobjp->isMesh())
				{
					if (dae)
					{
						LLSD mesh_header = gMeshRepo.getMeshHeader(sculpt_params->getSculptTexture());
						exportable = mesh_header["creator"].asUUID() == gAgentID;
					}
					else
					{
						// can not export mesh to oxp
						LL_INFOS("export") << "Mesh can not be exported to oxp." << LL_ENDL;
						return false;
					}
				}
				else if (sculpt_params)
				{
					LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(sculpt_params->getSculptTexture());
					if (imagep->mComment.find("a") != imagep->mComment.end())
					{
						exportable = (LLUUID(imagep->mComment["a"]) == gAgentID);
					}
					if (!exportable)
					{
						LLUUID asset_id = sculpt_params->getSculptTexture();
						LLViewerInventoryCategory::cat_array_t cats;
						LLViewerInventoryItem::item_array_t items;
						LLAssetIDMatches asset_id_matches(asset_id);
						gInventory.collectDescendentsIf(LLUUID::null, cats, items,
														LLInventoryModel::INCLUDE_TRASH,
														asset_id_matches);
						
						for (S32 i = 0; i < items.size(); ++i)
						{
							const LLPermissions perms = items[i]->getPermissions();
							exportable = perms.getCreator() == gAgentID;
						}
					}
					if (!exportable)
						LL_INFOS("export") << "Sculpt map has failed permissions check." << LL_ENDL;
				}
			}
#ifdef OPENSIM
			else if (LLGridManager::getInstance()->isInOpenSim())
			{
				if (sculpt_params && !volobjp->isMesh())
				{
					LLUUID asset_id = sculpt_params->getSculptTexture();
					LLViewerInventoryCategory::cat_array_t cats;
					LLViewerInventoryItem::item_array_t items;
					LLAssetIDMatches asset_id_matches(asset_id);
					gInventory.collectDescendentsIf(LLUUID::null, cats, items,
													LLInventoryModel::INCLUDE_TRASH,
													asset_id_matches);
					
					for (S32 i = 0; i < items.size(); ++i)
					{
						const LLPermissions perms = items[i]->getPermissions();
						switch (LFSimFeatureHandler::instance().exportPolicy())
						{
							case EXPORT_ALLOWED:
								exportable = (perms.getMaskOwner() & PERM_EXPORT) == PERM_EXPORT;
								break;
							/// TODO: Once enough grids adopt a version supporting exports, get consensus
							/// on whether we should allow full perm exports anymore.
							case EXPORT_UNDEFINED:
								exportable = (perms.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED;
								break;
							case EXPORT_DENIED:
							default:
								exportable = perms.getCreator() == gAgentID;
						}
						if (!exportable)
							LL_INFOS("export") << "Sculpt map has failed permissions check." << LL_ENDL;
					}
				}
				else
				{
					exportable = true;
				}
			}
#endif // OPENSIM
		}
		else
		{
			exportable = true;
		}
	}
	return exportable;
}