Beispiel #1
0
void LLHoverView::updateText()
{
	LLViewerObject* hit_object = getLastHoverObject();
	std::string line;

	mText.clear();
	if ( hit_object )
	{
		if ( hit_object->isHUDAttachment() )
		{
			// no hover tips for HUD elements, since they can obscure
			// what the HUD is displaying
			return;
		}

		if ( hit_object->isAttachment() )
		{
			// get root of attachment then parent, which is avatar
			LLViewerObject* root_edit = hit_object->getRootEdit();
			if (!root_edit)
			{
				// Strange parenting issue, don't show any text
				return;
			}
			hit_object = (LLViewerObject*)root_edit->getParent();
			if (!hit_object)
			{
				// another strange parenting issue, bail out
				return;
			}
		}

		line.clear();
		if (hit_object->isAvatar())
		{
			LLNameValue* title = hit_object->getNVPair("Title");
			LLNameValue* firstname = hit_object->getNVPair("FirstName");
			LLNameValue* lastname =  hit_object->getNVPair("LastName");
			if (firstname && lastname)
			{
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
				if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
				{
					line = RlvStrings::getAnonym(line.append(firstname->getString()).append(1, ' ').append(lastname->getString()));
				}
				else
				{
// [/RLVa:KB]
					if (title)
					{
						line.append(title->getString());
						line.append(1, ' ');
					}
					line.append(firstname->getString());
					line.append(1, ' ');
					line.append(lastname->getString());
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
				}
// [/RLVa:KB]
			}
			else
			{
				line.append(LLTrans::getString("TooltipPerson"));
			}
			mText.push_back(line);
		}
		else
		{
			//
			//  We have hit a regular object (not an avatar or attachment)
			// 

			//
			//  Default prefs will suppress display unless the object is interactive
			//
			BOOL suppressObjectHoverDisplay = !gSavedSettings.getBOOL("ShowAllObjectHoverTip");			
			
			LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();;
			if (nodep)
			{
				line.clear();
				if (nodep->mName.empty())
				{
					line.append(LLTrans::getString("TooltipNoName"));
				}
				else
				{
					line.append( nodep->mName );
				}
				mText.push_back(line);

				if (!nodep->mDescription.empty()
					&& nodep->mDescription != DEFAULT_DESC)
				{
					mText.push_back( nodep->mDescription );
				}

				// Line: "Owner: James Linden"
				line.clear();
				line.append(LLTrans::getString("TooltipOwner") + " ");

				if (nodep->mValid)
				{
					LLUUID owner;
					std::string name;
					if (!nodep->mPermissions->isGroupOwned())
					{
						owner = nodep->mPermissions->getOwner();
						if (LLUUID::null == owner)
						{
							line.append(LLTrans::getString("TooltipPublic"));
						}
						else if(gCacheName->getFullName(owner, name))
						{
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
							if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
							{
								name = RlvStrings::getAnonym(name);
							}
// [/RLVa:KB]

							line.append(name);
						}
						else
						{
							line.append(LLTrans::getString("RetrievingData"));
						}
					}
					else
					{
						std::string name;
						owner = nodep->mPermissions->getGroup();
						if (gCacheName->getGroupName(owner, name))
						{
							line.append(name);
							line.append(LLTrans::getString("TooltipIsGroup"));
						}
						else
						{
							line.append(LLTrans::getString("RetrievingData"));
						}
					}
				}
				else
				{
					line.append(LLTrans::getString("RetrievingData"));
				}
				mText.push_back(line);

				// Build a line describing any special properties of this object.
				LLViewerObject *object = hit_object;
				LLViewerObject *parent = (LLViewerObject *)object->getParent();

				if (object &&
					(object->usePhysics() ||
					 object->flagScripted() || 
					 object->flagHandleTouch() || (parent && parent->flagHandleTouch()) ||
					 object->flagTakesMoney() || (parent && parent->flagTakesMoney()) ||
					 object->flagAllowInventoryAdd() ||
					 object->flagTemporary() ||
					 object->flagPhantom()) )
				{
					line.clear();
					if (object->flagScripted())
					{
						
						line.append(LLTrans::getString("TooltipFlagScript") + " ");
					}

					if (object->usePhysics())
					{
						line.append(LLTrans::getString("TooltipFlagPhysics") + " ");
					}

					if (object->flagHandleTouch() || (parent && parent->flagHandleTouch()) )
					{
						line.append(LLTrans::getString("TooltipFlagTouch") + " ");
						suppressObjectHoverDisplay = FALSE;		//  Show tip
					}

					if (object->flagTakesMoney() || (parent && parent->flagTakesMoney()) )
					{
						line.append(LLTrans::getString("TooltipFlagL$") + " ");
						suppressObjectHoverDisplay = FALSE;		//  Show tip
					}

					if (object->flagAllowInventoryAdd())
					{
						line.append(LLTrans::getString("TooltipFlagDropInventory") + " ");
						suppressObjectHoverDisplay = FALSE;		//  Show tip
					}

					if (object->flagPhantom())
					{
						line.append(LLTrans::getString("TooltipFlagPhantom") + " ");
					}

					if (object->flagTemporary())
					{
						line.append(LLTrans::getString("TooltipFlagTemporary") + " ");
					}

					if (object->usePhysics() || 
						object->flagHandleTouch() ||
						(parent && parent->flagHandleTouch()) )
					{
						line.append(LLTrans::getString("TooltipFlagRightClickMenu") + " ");
					}
					mText.push_back(line);
				}

				// Free to copy / For Sale: L$
				line.clear();
				if (nodep->mValid)
				{
					BOOL for_copy = nodep->mPermissions->getMaskEveryone() & PERM_COPY && object->permCopy();
					BOOL for_sale = nodep->mSaleInfo.isForSale() &&
									nodep->mPermissions->getMaskOwner() & PERM_TRANSFER &&
									(nodep->mPermissions->getMaskOwner() & PERM_COPY ||
									 nodep->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY);
					if (for_copy)
					{
						line.append(LLTrans::getString("TooltipFreeToCopy"));
						suppressObjectHoverDisplay = FALSE;		//  Show tip
					}
					else if (for_sale)
					{
						LLStringUtil::format_map_t args;
						args["[AMOUNT]"] = llformat("%d", nodep->mSaleInfo.getSalePrice());
						line.append(LLTrans::getString("TooltipForSaleL$", args));
						suppressObjectHoverDisplay = FALSE;		//  Show tip
					}
					else
					{
						// Nothing if not for sale
						// line.append("Not for sale");
					}
				}
				else
				{
					LLStringUtil::format_map_t args;
					args["[MESSAGE]"] = LLTrans::getString("RetrievingData");
					line.append(LLTrans::getString("TooltipForSaleMsg", args));
				}
				mText.push_back(line);
			}
			line.clear();
			S32 prim_count = LLSelectMgr::getInstance()->getHoverObjects()->getObjectCount();
			line.append(llformat("Prims: %d", prim_count));
			mText.push_back(line);

			line.clear();
			line.append("Position: ");

			LLViewerRegion *region = gAgent.getRegion();
			LLVector3 position = region->getPosRegionFromGlobal(hit_object->getPositionGlobal());//regionp->getOriginAgent();
			LLVector3 mypos = region->getPosRegionFromGlobal(gAgent.getPositionGlobal());
			

			LLVector3 delta = position - mypos;
			F32 distance = (F32)delta.magVec();

			line.append(llformat("<%.02f,%.02f,%.02f>",position.mV[0],position.mV[1],position.mV[2]));
			mText.push_back(line);
			line.clear();
			line.append(llformat("Distance: %.02fm",distance));
			mText.push_back(line);
			
			//  If the hover tip shouldn't be shown, delete all the object text
			if (suppressObjectHoverDisplay)
			{
				mText.clear();
			}
		}
	}
	else if ( mHoverLandGlobal != LLVector3d::zero )
	{
		// 
		//  Do not show hover for land unless prefs are set to allow it.
		// 
		
		if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return; 

		// Didn't hit an object, but since we have a land point we
		// must be hovering over land.

		LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
		LLUUID owner;
		S32 width = 0;
		S32 height = 0;

		if ( hover_parcel )
		{
			owner = hover_parcel->getOwnerID();
			width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
			height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
		}

		// Line: "Land"
		line.clear();
		line.append(LLTrans::getString("TooltipLand"));
		if (hover_parcel)
		{
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-0.2.0b
			line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) 
				? hover_parcel->getName() : RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL) );
// [/RLVa:KB]
			//line.append(hover_parcel->getName());
		}
		mText.push_back(line);

		// Line: "Owner: James Linden"
		line.clear();
		line.append(LLTrans::getString("TooltipOwner") + " ");

		if ( hover_parcel )
		{
			std::string name;
			if (LLUUID::null == owner)
			{
				line.append(LLTrans::getString("TooltipPublic"));
			}
			else if (hover_parcel->getIsGroupOwned())
			{
				if (gCacheName->getGroupName(owner, name))
				{
					line.append(name);
					line.append(LLTrans::getString("TooltipIsGroup"));
				}
				else
				{
					line.append(LLTrans::getString("RetrievingData"));
				}
			}
			else if(gCacheName->getFullName(owner, name))
			{
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b
				line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? name : RlvStrings::getAnonym(name));
// [/RLVa:KB]
				//line.append(name);
			}
			else
			{
				line.append(LLTrans::getString("RetrievingData"));
			}
		}
		else
		{
			line.append(LLTrans::getString("RetrievingData"));
		}
		mText.push_back(line);

		// Line: "no fly, not safe, no build"

		// Don't display properties for your land.  This is just
		// confusing, because you can do anything on your own land.
		if ( hover_parcel && owner != gAgent.getID() )
		{
			S32 words = 0;
			
			line.clear();
			// JC - Keep this in the same order as the checkboxes
			// on the land info panel
			if ( !hover_parcel->getAllowModify() )
			{
				if ( hover_parcel->getAllowGroupModify() )
				{
					line.append(LLTrans::getString("TooltipFlagGroupBuild"));
				}
				else
				{
					line.append(LLTrans::getString("TooltipFlagNoBuild"));
				}
				words++;
			}

			if ( !hover_parcel->getAllowTerraform() )
			{
				if (words) line.append(", ");
				line.append(LLTrans::getString("TooltipFlagNoEdit"));
				words++;
			}

			if ( hover_parcel->getAllowDamage() )
			{
				if (words) line.append(", ");
				line.append(LLTrans::getString("TooltipFlagNotSafe"));
				words++;
			}

			// Maybe we should reflect the estate's block fly bit here as well?  DK 12/1/04
			if ( !hover_parcel->getAllowFly() )
			{
				if (words) line.append(", ");
				line.append(LLTrans::getString("TooltipFlagNoFly"));
				words++;
			}

			if ( !hover_parcel->getAllowOtherScripts() )
			{
				if (words) line.append(", ");
				if ( hover_parcel->getAllowGroupScripts() )
				{
					line.append(LLTrans::getString("TooltipFlagGroupScripts"));
				}
				else
				{
					line.append(LLTrans::getString("TooltipFlagNoScripts"));
				}
				
				words++;
			}

			if (words) 
			{
				mText.push_back(line);
			}
		}

		// Line: "Size: 1x4"
		// Only show for non-public land
		/*
		if ( hover_parcel && LLUUID::null != owner)
		{
			line = llformat("Size: %dx%d", width, height );
			mText.push_back(line);
		}
		*/
		if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE))
		{
			LLStringUtil::format_map_t args;
			args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice());
			line = LLTrans::getString("TooltipForSaleL$", args);
			mText.push_back(line);
		}
	}
}
void LLHoverView::updateText()
{
	LLViewerObject* hit_object = getLastHoverObject();
	std::string line;

	//<singu>
	if (hit_object == mLastTextHoverObject &&
		!(mLastTextHoverObjectTimer.getStarted() && mLastTextHoverObjectTimer.hasExpired()))
	{
		// mText is already up to date.
		return;
	}
	mLastTextHoverObject = hit_object;
	mLastTextHoverObjectTimer.stop();
	bool retrieving_data = false;
	//</singu>

	mText.clear();
	if ( hit_object )
	{
		if ( hit_object->isHUDAttachment() )
		{
			// no hover tips for HUD elements, since they can obscure
			// what the HUD is displaying
			return;
		}

		if ( hit_object->isAttachment() )
		{
			// get root of attachment then parent, which is avatar
			LLViewerObject* root_edit = hit_object->getRootEdit();
			if (!root_edit)
			{
				// Strange parenting issue, don't show any text
				return;
			}
			hit_object = (LLViewerObject*)root_edit->getParent();
			if (!hit_object)
			{
				// another strange parenting issue, bail out
				return;
			}
		}

		line.clear();
		if (hit_object->isAvatar())
		{
			LLNameValue* title = hit_object->getNVPair("Title");
			LLNameValue* firstname = hit_object->getNVPair("FirstName");
			LLNameValue* lastname =  hit_object->getNVPair("LastName");
			if (firstname && lastname)
			{
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
				if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
				{
					line = RlvStrings::getAnonym(line.append(firstname->getString()).append(1, ' ').append(lastname->getString()));
				}
				else
				{
// [/RLVa:KB]
					std::string complete_name;
					if (!LLAvatarNameCache::getNSName(hit_object->getID(), complete_name))
						complete_name = firstname->getString() + std::string(" ") + lastname->getString();

					if (title)
					{
						line.append(title->getString());
						line.append(1, ' ');
					}
					line += complete_name;
					
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
				}
// [/RLVa:KB]
			}
			else
			{
				line.append(LLTrans::getString("TooltipPerson"));
			}
			mText.push_back(line);
		}
		else
		{
			//
			//  We have hit a regular object (not an avatar or attachment)
			// 

			//
			//  Default prefs will suppress display unless the object is interactive
			//
			BOOL suppressObjectHoverDisplay = !gSavedSettings.getBOOL("ShowAllObjectHoverTip");			
			
			LLSelectNode *nodep = LLSelectMgr::getInstance()->getHoverNode();
			if (nodep)
			{
				line.clear();

				bool for_copy = nodep->mValid && nodep->mPermissions->getMaskEveryone() & PERM_COPY && hit_object && hit_object->permCopy();
				bool for_sale = nodep->mValid && for_sale_selection(nodep);
				
				bool has_media = false;
				bool is_time_based_media = false;
				bool is_web_based_media = false;
				bool is_media_playing = false;
				bool is_media_displaying = false;
			
				// Does this face have media?
				const LLTextureEntry* tep = hit_object ? hit_object->getTE(mLastPickInfo.mObjectFace) : NULL;
			
				if(tep)
				{
					has_media = tep->hasMedia();
					const LLMediaEntry* mep = has_media ? tep->getMediaData() : NULL;
					if (mep)
					{
						viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
						LLPluginClassMedia* media_plugin = NULL;
					
						if (media_impl.notNull() && (media_impl->hasMedia()))
						{
							is_media_displaying = true;
							//LLStringUtil::format_map_t args;
						
							media_plugin = media_impl->getMediaPlugin();
							if(media_plugin)
							{	
								if(media_plugin->pluginSupportsMediaTime())
								{
									is_time_based_media = true;
									is_web_based_media = false;
									//args["[CurrentURL]"] =  media_impl->getMediaURL();
									is_media_playing = media_impl->isMediaPlaying();
								}
								else
								{
									is_time_based_media = false;
									is_web_based_media = true;
									//args["[CurrentURL]"] =  media_plugin->getLocation();
								}
								//tooltip_msg.append(LLTrans::getString("CurrentURL", args));
							}
						}
					}
				}

				
				// Avoid showing tip over media that's displaying unless it's for sale
				// also check the primary node since sometimes it can have an action even though
				// the root node doesn't

				if(!suppressObjectHoverDisplay || !is_media_displaying || for_sale)
				{
					if (nodep->mName.empty())
					{
						line.append(LLTrans::getString("TooltipNoName"));
					}
					else
					{
						line.append( nodep->mName );
					}

					mText.push_back(line);

					if (!nodep->mDescription.empty()
						&& nodep->mDescription != DEFAULT_DESC)
					{
						mText.push_back( nodep->mDescription );
					}

					// Line: "Owner: James Linden"
					line.clear();
					line.append(LLTrans::getString("TooltipOwner") + " ");

					if (nodep->mValid)
					{
						LLUUID owner;
						std::string name;
						if (!nodep->mPermissions->isGroupOwned())
						{
							owner = nodep->mPermissions->getOwner();
							if (LLUUID::null == owner)
							{
								line.append(LLTrans::getString("TooltipPublic"));
							}
							else if (LLAvatarNameCache::getNSName(owner, name))
							{
	// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
								if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
								{
									name = RlvStrings::getAnonym(name);
								}
	// [/RLVa:KB]

								line.append(name);
							}
							else
							{
								line.append(LLTrans::getString("RetrievingData"));
								retrieving_data = true;
							}
						}
						else
						{
							std::string name;
							owner = nodep->mPermissions->getGroup();
							if (gCacheName->getGroupName(owner, name))
							{
								line.append(name);
								line.append(LLTrans::getString("TooltipIsGroup"));
							}
							else
							{
								line.append(LLTrans::getString("RetrievingData"));
								retrieving_data = true;
							}
						}
					}
					else
					{
						line.append(LLTrans::getString("RetrievingData"));
						retrieving_data = true;
					}
					mText.push_back(line);

					// Build a line describing any special properties of this object.
					LLViewerObject *object = hit_object;
					LLViewerObject *parent = (LLViewerObject *)object->getParent();

					if (object &&
						(object->flagUsePhysics() ||
						 object->flagScripted() || 
						 object->flagHandleTouch() || (parent && parent->flagHandleTouch()) ||
						 object->flagTakesMoney() || (parent && parent->flagTakesMoney()) ||
						 object->flagAllowInventoryAdd() ||
						 object->flagTemporary() ||
						 object->flagPhantom()) )
					{
						line.clear();
						if (object->flagScripted())
						{
						
							line.append(LLTrans::getString("TooltipFlagScript") + " ");
						}

						if (object->flagUsePhysics())
						{
							line.append(LLTrans::getString("TooltipFlagPhysics") + " ");
						}

						if (object->flagHandleTouch() || (parent && parent->flagHandleTouch()) )
						{
							line.append(LLTrans::getString("TooltipFlagTouch") + " ");
							suppressObjectHoverDisplay = FALSE;		//  Show tip
						}

						if (object->flagTakesMoney() || (parent && parent->flagTakesMoney()) )
						{
							line.append(gHippoGridManager->getConnectedGrid()->getCurrencySymbol() + " ");
							suppressObjectHoverDisplay = FALSE;		//  Show tip
						}

						if (object->flagAllowInventoryAdd())
						{
							line.append(LLTrans::getString("TooltipFlagDropInventory") + " ");
							suppressObjectHoverDisplay = FALSE;		//  Show tip
						}

						if (object->flagPhantom())
						{
							line.append(LLTrans::getString("TooltipFlagPhantom") + " ");
						}

						if (object->flagTemporary())
						{
							line.append(LLTrans::getString("TooltipFlagTemporary") + " ");
						}

						if (object->flagUsePhysics() || 
							object->flagHandleTouch() ||
							(parent && parent->flagHandleTouch()) )
						{
							line.append(LLTrans::getString("TooltipFlagRightClickMenu") + " ");
						}
						mText.push_back(line);
					}

					// Free to copy / For Sale: L$
					line.clear();
					if (nodep->mValid)
					{
						if (for_copy)
						{
							line.append(LLTrans::getString("TooltipFreeToCopy"));
							suppressObjectHoverDisplay = FALSE;		//  Show tip
						}
						else if (for_sale)
						{
							LLStringUtil::format_map_t args;
							args["[AMOUNT]"] = llformat("%d", nodep->mSaleInfo.getSalePrice());
							line.append(LLTrans::getString("TooltipForSaleL$", args));
							suppressObjectHoverDisplay = FALSE;		//  Show tip
						}
						else
						{
							// Nothing if not for sale
							// line.append("Not for sale");
						}
					}
					else
					{
						LLStringUtil::format_map_t args;
						args["[MESSAGE]"] = LLTrans::getString("RetrievingData");
						retrieving_data = true;
						line.append(LLTrans::getString("TooltipForSaleMsg", args));
					}
					mText.push_back(line);
					line.clear();
					S32 prim_count = LLSelectMgr::getInstance()->getHoverObjects()->getObjectCount();
					line.append(llformat("Prims: %d", prim_count));
					mText.push_back(line);

					line.clear();
					line.append("Position: ");

					LLViewerRegion *region = gAgent.getRegion();
					LLVector3 position = region->getPosRegionFromGlobal(hit_object->getPositionGlobal());//regionp->getOriginAgent();
					LLVector3 mypos = region->getPosRegionFromGlobal(gAgent.getPositionGlobal());
			

					LLVector3 delta = position - mypos;
					F32 distance = (F32)delta.magVec();

					line.append(llformat("<%.02f,%.02f,%.02f>",position.mV[0],position.mV[1],position.mV[2]));
					mText.push_back(line);
					line.clear();
					line.append(llformat("Distance: %.02fm",distance));
					mText.push_back(line);
				}
				else
				{
					suppressObjectHoverDisplay = TRUE;
				}
				//  If the hover tip shouldn't be shown, delete all the object text
				if (suppressObjectHoverDisplay)
				{
					mText.clear();
				}
			}
		}
	}
	else if ( mHoverLandGlobal != LLVector3d::zero )
	{
		// 
		//  Do not show hover for land unless prefs are set to allow it.
		// 
		
		if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return; 

		// Didn't hit an object, but since we have a land point we
		// must be hovering over land.

		LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
		LLUUID owner;

		if ( hover_parcel )
		{
			owner = hover_parcel->getOwnerID();
		}

		// Line: "Land"
		line.clear();
		line.append(LLTrans::getString("TooltipLand"));
		if (hover_parcel)
		{
// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) | Added: RLVa-0.2.0b
			line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) 
				? hover_parcel->getName() : RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL) );
// [/RLVa:KB]
			//line.append(hover_parcel->getName());
		}
		mText.push_back(line);

		// Line: "Owner: James Linden"
		line.clear();
		line.append(LLTrans::getString("TooltipOwner") + " ");

		if ( hover_parcel )
		{
			std::string name;
			if (LLUUID::null == owner)
			{
				line.append(LLTrans::getString("TooltipPublic"));
			}
			else if (hover_parcel->getIsGroupOwned())
			{
				if (gCacheName->getGroupName(owner, name))
				{
					line.append(name);
					line.append(LLTrans::getString("TooltipIsGroup"));
				}
				else
				{
					line.append(LLTrans::getString("RetrievingData"));
					retrieving_data = true;
				}
			}
			else if(gCacheName->getFullName(owner, name))
			{
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b
				line.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? name : RlvStrings::getAnonym(name));
// [/RLVa:KB]
				//line.append(name);
			}
			else
			{
				line.append(LLTrans::getString("RetrievingData"));
				retrieving_data = true;
			}
		}
		else
		{
			line.append(LLTrans::getString("RetrievingData"));
			retrieving_data = true;
		}
		mText.push_back(line);

		// Line: "no fly, not safe, no build"

		// Don't display properties for your land.  This is just
		// confusing, because you can do anything on your own land.
		if ( hover_parcel && owner != gAgent.getID() )
		{
			S32 words = 0;
			
			line.clear();
			// JC - Keep this in the same order as the checkboxes
			// on the land info panel
			if ( !hover_parcel->getAllowModify() )
			{
				if ( hover_parcel->getAllowGroupModify() )
				{
					line.append(LLTrans::getString("TooltipFlagGroupBuild"));
				}
				else
				{
					line.append(LLTrans::getString("TooltipFlagNoBuild"));
				}
				words++;
			}

			if ( !hover_parcel->getAllowTerraform() )
			{
				if (words) line.append(", ");
				line.append(LLTrans::getString("TooltipFlagNoEdit"));
				words++;
			}

			if ( hover_parcel->getAllowDamage() )
			{
				if (words) line.append(", ");
				line.append(LLTrans::getString("TooltipFlagNotSafe"));
				words++;
			}

			// Maybe we should reflect the estate's block fly bit here as well?  DK 12/1/04
			if ( !hover_parcel->getAllowFly() )
			{
				if (words) line.append(", ");
				line.append(LLTrans::getString("TooltipFlagNoFly"));
				words++;
			}

			if ( !hover_parcel->getAllowOtherScripts() )
			{
				if (words) line.append(", ");
				if ( hover_parcel->getAllowGroupScripts() )
				{
					line.append(LLTrans::getString("TooltipFlagGroupScripts"));
				}
				else
				{
					line.append(LLTrans::getString("TooltipFlagNoScripts"));
				}
				
				words++;
			}

			if (words) 
			{
				mText.push_back(line);
			}
		}

		if (hover_parcel && hover_parcel->getParcelFlag(PF_FOR_SALE))
		{
			LLStringUtil::format_map_t args;
			args["[AMOUNT]"] = llformat("%d", hover_parcel->getSalePrice());
			line = LLTrans::getString("TooltipForSaleL$", args);
			mText.push_back(line);
		}
	}

	//<singu>
	if (retrieving_data)
	{
		// Keep doing this twice per second, until all data was retrieved.
		mLastTextHoverObjectTimer.start(DELAY_BEFORE_REFRESH_TIP);
	}
	//</singu>
}
Beispiel #3
0
LLSD JCExportTracker::subserialize(LLViewerObject* linkset)
{
	//Chalice - Changed to support exporting linkset groups.
	LLViewerObject* object = linkset;
	//if(!linkset)return LLSD();
	
	// Create an LLSD object that will hold the entire tree structure that can be serialized to a file
	LLSD llsd;

	//if (!node)
	//	return llsd;

	//object = root_object = node->getObject();
	
	if (!object)
		return llsd;
	if(!(!object->isAvatar() && object->permYouOwner() && object->permModify() && object->permCopy() && object->permTransfer() && !gAgent.getGodLevel()))
		return llsd;
	// Build a list of everything that we'll actually be exporting
	LLDynamicArray<LLViewerObject*> export_objects;
	
	// Add the root object to the export list
	export_objects.put(object);
	
	// Iterate over all of this objects children
	LLViewerObject::child_list_t child_list = object->getChildren();
	
	for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
	{
		LLViewerObject* child = *i;
		if(!child->isAvatar())
		{
			// Put the child objects on the export list
			export_objects.put(child);
		}
	}
		
	S32 object_index = 0;
	
	while ((object_index < export_objects.count()))
	{
		object = export_objects.get(object_index++);
		LLUUID id = object->getID();
	
		llinfos << "Exporting prim " << object->getID().asString() << llendl;
	
		// Create an LLSD object that represents this prim. It will be injected in to the overall LLSD
		// tree structure
		LLSD prim_llsd;
	
		if (object_index == 1)
		{
			LLVOAvatar* avatar = find_avatar_from_object(object);
			if (avatar)
			{
				LLViewerJointAttachment* attachment = avatar->getTargetAttachmentPoint(object);
				U8 attachment_id = 0;
				
				if (attachment)
				{
					for (LLVOAvatar::attachment_map_t::iterator iter = avatar->mAttachmentPoints.begin();
										iter != avatar->mAttachmentPoints.end(); ++iter)
					{
						if (iter->second == attachment)
						{
							attachment_id = iter->first;
							break;
						}
					}
				}
				else
				{
					// interpret 0 as "default location"
					attachment_id = 0;
				}
				
				prim_llsd["Attachment"] = attachment_id;
				prim_llsd["attachpos"] = object->getPosition().getValue();
				prim_llsd["attachrot"] = ll_sd_from_quaternion(object->getRotation());
			}
			
			prim_llsd["position"] = LLVector3(0, 0, 0).getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
		}
		else
		{
			prim_llsd["position"] = object->getPosition().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
		}
		//prim_llsd["name"] = "";//node->mName;
		//prim_llsd["description"] = "";//node->mDescription;
		// Transforms
		prim_llsd["scale"] = object->getScale().getValue();
		// Flags
		prim_llsd["shadows"] = object->flagCastShadows();
		prim_llsd["phantom"] = object->flagPhantom();
		prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS);
		LLVolumeParams params = object->getVolume()->getParams();
		prim_llsd["volume"] = params.asLLSD();
		if (object->isFlexible())
		{
			LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
			prim_llsd["flexible"] = flex->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
		{
			LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
			prim_llsd["light"] = light->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
		{
			LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			prim_llsd["sculpt"] = sculpt->asLLSD();
		}

		// Textures
		LLSD te_llsd;
		U8 te_count = object->getNumTEs();
		
		for (U8 i = 0; i < te_count; i++)
		{
			te_llsd.append(object->getTE(i)->asLLSD());
		}

		if(export_textures)
		{
			std::string path = asset_dir + gDirUtilp->getDirDelimiter();
			for (U8 i = 0; i < te_count; i++)
			{
				LLUUID asset_id = object->getTE(i)->getID();
				JCAssetInfo* info = new JCAssetInfo;
				info->path = path + asset_id.asString() + ".j2c";
				info->name = "Prim Texture";
				//gAssetStorage->getAssetData(asset_id, LLAssetType::AT_TEXTURE, JCAssetExportCallback, info,1);
				if(requested_textures.count(asset_id) == 0)
				{
					requested_textures.insert(asset_id);
					LLViewerImage* img = gImageList.getImage(asset_id, MIPMAP_TRUE, FALSE);
					img->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAX_LEVEL);
					img->setLoadedCallback( JCExportTracker::onFileLoadedForSave, 
									0, TRUE, FALSE, info );
					llinfos << "Requesting texture " << asset_id.asString() << llendl;
				}
			}
		}

		//JCExportTracker::mirror(asset, obj, asset_dir, asset->getUUID().asString());
		
		prim_llsd["textures"] = te_llsd;

		prim_llsd["id"] = object->getID().asString();
		if(export_properties)
		{
			////cmdline_printchat(llformat("yes %d",export_properties));
			propertyqueries += 1;
			gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
			gMessageSystem->nextBlockFast(_PREHASH_AgentData);
			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
			gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());

			gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
            gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
            
            gMessageSystem->sendReliable(gAgent.getRegionHost());

			if(export_inventory)
			{
				object->registerInventoryListener(sInstance,NULL);
				object->dirtyInventory();
				object->requestInventory();
				invqueries += 1;
			}
		}//else //cmdline_printchat(llformat("no %d",export_properties));
		totalprims += 1;

		// Changed to use link numbers zero-indexed.
		llsd[object_index - 1] = prim_llsd;
	}
	return llsd;
}
LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool is_attachment)
{
	LLViewerObject* object;
	LLSD llsd;
	char localid[16];

	for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
	{
		object = (*i);
		LLUUID id = object->getID();

		LL_INFOS("ObjectBackup") << "Exporting prim " << object->getID().asString() << LL_ENDL;

		// Create an LLSD object that represents this prim. It will be injected in to the overall LLSD
		// tree structure
		LLSD prim_llsd;

		if (!object->isRoot())
		{
			// Parent id
			snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID());
			prim_llsd["parent"] = localid;
		}

		// Name and description
		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(object);
		if (node)
		{
			prim_llsd["name"] = node->mName;
			prim_llsd["description"] = node->mDescription;
		}

		// Transforms
		if (is_attachment)
		{
			prim_llsd["position"] = object->getPositionEdit().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotationEdit());
		}
		else
		{
			prim_llsd["position"] = object->getPosition().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
		}
		prim_llsd["scale"] = object->getScale().getValue();

		// Flags
		prim_llsd["shadows"] = FALSE;
		prim_llsd["phantom"] = object->flagPhantom();
		prim_llsd["physical"] = object->flagUsePhysics();

		// Volume params
		LLVolumeParams params = object->getVolume()->getParams();
		prim_llsd["volume"] = params.asLLSD();

		// Extra paramsb6fab961-af18-77f8-cf08-f021377a7244
		if (object->isFlexible())
		{
			// Flexible
			LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
			prim_llsd["flexible"] = flex->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
		{
			// Light
			LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
			prim_llsd["light"] = light->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
		{
			// Sculpt
			LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			prim_llsd["sculpt"] = sculpt->asLLSD();

			LLUUID sculpt_texture = sculpt->getSculptTexture();
			if (sculpt_texture == validateTextureID(sculpt_texture))
			{
				bool alreadyseen = false;
				std::list<LLUUID>::iterator iter;
				for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) 
				{
					if ((*iter) == sculpt_texture)
						alreadyseen = true;
				}
				if (alreadyseen == false)
				{
					LL_INFOS("ObjectBackup") << "Found a sculpt texture, adding to list " << sculpt_texture << LL_ENDL;
					mTexturesList.push_back(sculpt_texture);
				}
			}
			else
			{
				LL_WARNS("ObjectBackup") << "Incorrect permission to export a sculpt texture." << LL_ENDL;
				LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED;
			}
		}

		// Textures
		LLSD te_llsd;
		LLSD this_te_llsd;
		LLUUID t_id;
		U8 te_count = object->getNumTEs();
		for (U8 i = 0; i < te_count; i++)
		{
			bool alreadyseen = false;
			t_id = validateTextureID(object->getTE(i)->getID());
			this_te_llsd = object->getTE(i)->asLLSD();
			this_te_llsd["imageid"] = t_id;
			te_llsd.append(this_te_llsd);
			// Do not export Linden textures even though they don't taint creation.
			if (t_id != LL_TEXTURE_PLYWOOD && 
			    t_id != LL_TEXTURE_BLANK && 
			    t_id != LL_TEXTURE_TRANSPARENT &&
			    t_id != LL_TEXTURE_INVISIBLE &&
			    t_id != LL_TEXTURE_MEDIA)
 			{
				std::list<LLUUID>::iterator iter;
				for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) 
				{
					if ((*iter) == t_id)
						alreadyseen = true;
				}
				if (alreadyseen == false)
					mTexturesList.push_back(t_id);
			}
		}
		prim_llsd["textures"] = te_llsd;

		// The keys in the primitive maps do not have to be localids, they can be any
		// string. We simply use localids because they are a unique identifier
		snprintf(localid, sizeof(localid), "%u", object->getLocalID());
		llsd[(const char*)localid] = prim_llsd;
	}
	updateExportNumbers();
	return llsd;
}
LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list,
								 bool is_attachment)
{
	LLViewerObject* object;
	LLSD llsd;
	char localid[16];
	LLUUID t_id;

	for (LLViewerObject::child_list_t::iterator i = child_list.begin();
		 i != child_list.end(); ++i)
	{
		object = (*i);
		LLUUID id = object->getID();

		LL_INFOS() << "Exporting prim " << object->getID().asString() << LL_ENDL;

		// Create an LLSD object that represents this prim. It will be injected
		// in to the overall LLSD tree structure
		LLSD prim_llsd;

		if (!object->isRoot())
		{
			// Parent id
			snprintf(localid, sizeof(localid), "%u",
					 object->getSubParent()->getLocalID());
			prim_llsd["parent"] = localid;
		}

		// Name and description
		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(object);
		if (node)
		{
			prim_llsd["name"] = node->mName;
			prim_llsd["description"] = node->mDescription;
		}

		// Transforms
		if (is_attachment)
		{
			prim_llsd["position"] = object->getPositionEdit().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotationEdit());
		}
		else
		{
			prim_llsd["position"] = object->getPosition().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
		}
		prim_llsd["scale"] = object->getScale().getValue();

		// Flags
		prim_llsd["phantom"] = object->flagPhantom();		// legacy
		prim_llsd["physical"] = object->flagUsePhysics();	// legacy
		prim_llsd["flags"] = (S32)object->getFlags();		// new way

		// Extra physics flags
		if (mGotExtraPhysics)
		{
			LLSD& physics = prim_llsd["ExtraPhysics"];
			physics["PhysicsShapeType"] = object->getPhysicsShapeType();
			physics["Gravity"] = object->getPhysicsGravity();
			physics["Friction"] = object->getPhysicsFriction();
			physics["Density"] = object->getPhysicsDensity();
			physics["Restitution"] = object->getPhysicsRestitution();
		}

		// Click action
		if (S32 action = object->getClickAction()) // Non-zero
			prim_llsd["clickaction"] = action;

		// Prim material
		prim_llsd["material"] = object->getMaterial();

		// Volume params
		LLVolumeParams params = object->getVolume()->getParams();
		prim_llsd["volume"] = params.asLLSD();

		// Extra paramsb6fab961-af18-77f8-cf08-f021377a7244

		if (object->isFlexible())
		{
			// Flexible
			LLFlexibleObjectData* flex;
			flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
			prim_llsd["flexible"] = flex->asLLSD();
		}

		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
		{
			// Light
			LLLightParams* light;
			light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
			prim_llsd["light"] = light->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
		{
			// Light image
			LLLightImageParams* light_param;
			light_param = (LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
			t_id = validateTextureID(light_param->getLightTexture());
			if (mTexturesList.count(t_id) == 0)
			{
				LL_INFOS() << "Found a light texture, adding to list " << t_id
						<< LL_ENDL;
				mTexturesList.insert(t_id);
			}
			prim_llsd["light_texture"] = light_param->asLLSD();
		}

		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
		{
			// Sculpt
			LLSculptParams* sculpt;
			sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			prim_llsd["sculpt"] = sculpt->asLLSD();
			if ((sculpt->getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
			{
				LLUUID sculpt_texture = sculpt->getSculptTexture();
				if (sculpt_texture == validateTextureID(sculpt_texture))
				{
					if (mTexturesList.count(sculpt_texture) == 0)
					{
						LL_INFOS() << "Found a sculpt texture, adding to list "
								<< sculpt_texture << LL_ENDL;
						mTexturesList.insert(sculpt_texture);
					}
				}
				else
				{
					LL_WARNS() << "Incorrect permission to export a sculpt texture."
							<< LL_ENDL;
					mExportState = EXPORT_FAILED;
				}
			}
		}

		// Textures and materials
		LLSD te_llsd;
		LLSD this_te_llsd;
		LLSD te_mat_llsd;
		LLSD this_te_mat_llsd;
		bool has_materials = false;
		for (U8 i = 0, count = object->getNumTEs(); i < count; ++i)
		{
			LLTextureEntry* te = object->getTE(i);
			if (!te) continue;	// Paranoia

			// Normal texture/diffuse map
			t_id = validateTextureID(te->getID());
			this_te_llsd = te->asLLSD();
			this_te_llsd["imageid"] = t_id;
			te_llsd.append(this_te_llsd);
			// Do not export non-existent default textures
			if (t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE)
			{
				if (mTexturesList.count(t_id) == 0)
				{
					mTexturesList.insert(t_id);
				}
			}

			// Materials
			LLMaterial* mat = te->getMaterialParams().get();
			if (mat)
			{
				has_materials = true;
				this_te_mat_llsd = mat->asLLSD();

				t_id = validateTextureID(mat->getNormalID());
				this_te_mat_llsd["NormMap"] = t_id;
				if (mTexturesList.count(t_id) == 0)
				{
					mTexturesList.insert(t_id);
				}

				t_id = validateTextureID(mat->getSpecularID());
				this_te_mat_llsd["SpecMap"] = t_id;
				if (mTexturesList.count(t_id) == 0)
				{
					mTexturesList.insert(t_id);
				}

				te_mat_llsd.append(this_te_mat_llsd);
			}
		}
		prim_llsd["textures"] = te_llsd;
		if (has_materials)
		{
			prim_llsd["materials"] = te_mat_llsd;
		}

		// The keys in the primitive maps do not have to be localids, they can
		// be any string. We simply use localids because they are a unique
		// identifier
		snprintf(localid, sizeof(localid), "%u", object->getLocalID());
		llsd[(const char*)localid] = prim_llsd;
	}

	updateExportNumbers();

	return llsd;
}
LLSD primbackup::prims_to_llsd(LLViewerObject::child_list_t child_list)
{

	LLViewerObject* object;
	LLSD llsd;

	char localid[16];

	for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
	{
		object=(*i);
		LLUUID id = object->getID();

		llinfos << "Exporting prim " << object->getID().asString() << llendl;

		// Create an LLSD object that represents this prim. It will be injected in to the overall LLSD
		// tree structure
		LLSD prim_llsd;

		if (!object->isRoot())
		{

			// Parent id
			snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID());
			prim_llsd["parent"] = localid;
		}

		// Transforms
		prim_llsd["position"] = object->getPosition().getValue();
		prim_llsd["scale"] = object->getScale().getValue();
		prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());

		// Flags
		prim_llsd["shadows"] = object->flagCastShadows();
		prim_llsd["phantom"] = object->flagPhantom();
		prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS);

		// Volume params
		LLVolumeParams params = object->getVolume()->getParams();
		prim_llsd["volume"] = params.asLLSD();

		// Extra paramsb6fab961-af18-77f8-cf08-f021377a7244
		if (object->isFlexible())
		{
			// Flexible
			LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
			prim_llsd["flexible"] = flex->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
		{
			// Light
			LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
			prim_llsd["light"] = light->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
		{
			// Sculpt
			LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			prim_llsd["sculpt"] = sculpt->asLLSD();
			
			LLUUID sculpt_texture=sculpt->getSculptTexture();
			bool alreadyseen=false;
			std::list<LLUUID>::iterator iter;
			for(iter = textures.begin(); iter != textures.end() ; iter++) 
			{
				if( (*iter)==sculpt_texture)
					alreadyseen=true;
			}
			if(alreadyseen==false)
			{
				llinfos << "Found a sculpt texture, adding to list "<<sculpt_texture<<llendl;
				textures.push_back(sculpt_texture);
			}
		}

		// Textures
		LLSD te_llsd;
		U8 te_count = object->getNumTEs();
		for (U8 i = 0; i < te_count; i++)
		{
			bool alreadyseen=false;
			te_llsd.append(object->getTE(i)->asLLSD());
			std::list<LLUUID>::iterator iter;
			for(iter = textures.begin(); iter != textures.end() ; iter++) 
			{
				if( (*iter)==object->getTE(i)->getID())
					alreadyseen=true;
			}
			if(alreadyseen==false)
				textures.push_back(object->getTE(i)->getID());
		}
		prim_llsd["textures"] = te_llsd;

		// The keys in the primitive maps do not have to be localids, they can be any
		// string. We simply use localids because they are a unique identifier
		snprintf(localid, sizeof(localid), "%u", object->getLocalID());
		llsd[(const char*)localid] = prim_llsd;
	}

	updateexportnumbers();

	return llsd;
}