BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str)
{
	S32 in_len = in_str.length();

	item_map_t::iterator it;
	for (it = mActive.begin(); it != mActive.end(); ++it)
	{
		LLMultiGesture* gesture = (*it).second;
		if (gesture)
		{
			const std::string& trigger = gesture->getTrigger();
			
			if (in_len > (S32)trigger.length())
			{
				// too short, bail out
				continue;
			}

			std::string trigger_trunc = trigger;
			LLStringUtil::truncate(trigger_trunc, in_len);
			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
			{
				*out_str = trigger;
				return TRUE;
			}
		}
	}
	return FALSE;
}
void LLGestureMgr::update()
{
	S32 i;
	for (i = 0; i < (S32)mPlaying.size(); ++i)
	{
		stepGesture(mPlaying[i]);
	}

	// Clear out gestures that are done, by moving all the
	// ones that are still playing to the front.
	std::vector<LLMultiGesture*>::iterator new_end;
	new_end = std::partition(mPlaying.begin(),
							 mPlaying.end(),
							 IsGesturePlaying());

	// Something finished playing
	if (new_end != mPlaying.end())
	{
		// Delete the completed gestures that want deletion
		std::vector<LLMultiGesture*>::iterator it;
		for (it = new_end; it != mPlaying.end(); ++it)
		{
			LLMultiGesture* gesture = *it;

			if (gesture->mDoneCallback)
			{
				gesture->mDoneCallback(gesture);

				// callback might have deleted gesture, can't
				// rely on this pointer any more
				gesture = NULL;
			}
		}

		// And take done gestures out of the playing list
		mPlaying.erase(new_end, mPlaying.end());

		notifyObservers();
	}
}
Example #3
0
// static
void LLPreviewGesture::onLoadComplete(LLVFS *vfs,
									   const LLUUID& asset_uuid,
									   LLAssetType::EType type,
									   void* user_data, S32 status)
{
	LLUUID* item_idp = (LLUUID*)user_data;
	LLPreview* preview = LLPreview::find(*item_idp);
	if (preview)
	{
		LLPreviewGesture* self = (LLPreviewGesture*)preview;

		if (0 == status)
		{
			LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
			S32 size = file.getSize();

			char* buffer = new char[size+1];
			file.read((U8*)buffer, size);		/*Flawfinder: ignore*/
			buffer[size] = '\0';

			LLMultiGesture* gesture = new LLMultiGesture();

			LLDataPackerAsciiBuffer dp(buffer, size+1);
			BOOL ok = gesture->deserialize(dp);

			if (ok)
			{
				// Everything has been successful.  Load up the UI.
				self->loadUIFromGesture(gesture);

				self->mStepList->selectFirstItem();

				self->mDirty = FALSE;
				self->refresh();
			}
			else
			{
				llwarns << "Unable to load gesture" << llendl;
			}

			delete gesture;
			gesture = NULL;

			delete [] buffer;
			buffer = NULL;

			self->mAssetStatus = PREVIEW_ASSET_LOADED;
		}
		else
		{
			if( gViewerStats )
			{
				gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
			}

			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
				LL_ERR_FILE_EMPTY == status)
			{
				LLNotifyBox::showXml("GestureMissing");
			}
			else
			{
				LLNotifyBox::showXml("UnableToLoadGesture");
			}

			llwarns << "Problem loading gesture: " << status << llendl;
			self->mAssetStatus = PREVIEW_ASSET_ERROR;
		}
	}
	delete item_idp;
	item_idp = NULL;
}
Example #4
0
void LLPreviewGesture::saveIfNeeded()
{
	if (!gAssetStorage)
	{
		llwarns << "Can't save gesture, no asset storage system." << llendl;
		return;
	}

	if (!mDirty)
	{
		return;
	}

	// Copy the UI into a gesture
	LLMultiGesture* gesture = createGesture();

	// Serialize the gesture
	S32 max_size = gesture->getMaxSerialSize();
	char* buffer = new char[max_size];

	LLDataPackerAsciiBuffer dp(buffer, max_size);

	BOOL ok = gesture->serialize(dp);

	if (dp.getCurrentSize() > 1000)
	{
		gViewerWindow->alertXml("GestureSaveFailedTooManySteps");

		delete gesture;
		gesture = NULL;
	}
	else if (!ok)
	{
		gViewerWindow->alertXml("GestureSaveFailedTryAgain");
		delete gesture;
		gesture = NULL;
	}
	else
	{
		// Every save gets a new UUID.  Yup.
		LLTransactionID tid;
		LLAssetID asset_id;
		tid.generate();
		asset_id = tid.makeAssetID(gAgent.getSecureSessionID());

		LLVFile file(gVFS, asset_id, LLAssetType::AT_GESTURE, LLVFile::APPEND);

		S32 size = dp.getCurrentSize();
		file.setMaxSize(size);
		file.write((U8*)buffer, size);

		// Upload that asset to the database
		const LLInventoryItem* item = getItem();
		if (item)
		{
			std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
			std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory");
			if (mObjectUUID.isNull() && !agent_url.empty())
			{
				// Saving into agent inventory
				LLSD body;
				body["item_id"] = mItemUUID;
				LLHTTPClient::post(agent_url, body,
					new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
			}
			else if (!mObjectUUID.isNull() && !task_url.empty())
			{
				// Saving into task inventory
				LLSD body;
				body["task_id"] = mObjectUUID;
				body["item_id"] = mItemUUID;
				LLHTTPClient::post(task_url, body,
					new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
			}
			else if (gAssetStorage)
			{
				LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc");
				LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid);
				gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE);
			}
		}

		// If this gesture is active, then we need to update the in-memory
		// active map with the new pointer.
		if (gGestureManager.isGestureActive(mItemUUID))
		{
			// gesture manager now owns the pointer
			gGestureManager.replaceGesture(mItemUUID, gesture, asset_id);

			// replaceGesture may deactivate other gestures so let the
			// inventory know.
			gInventory.notifyObservers();
		}
		else
		{
			// we're done with this gesture
			delete gesture;
			gesture = NULL;
		}

		mDirty = FALSE;
		refresh();
	}

	delete [] buffer;
	buffer = NULL;
}
// static
void LLPreviewGesture::onLoadComplete(LLVFS *vfs,
									   const LLUUID& asset_uuid,
									   LLAssetType::EType type,
									   void* user_data, S32 status, LLExtStat ext_status)
{
	LLUUID* item_idp = (LLUUID*)user_data;
	LLPreview* preview = LLPreview::find(*item_idp);
	if (preview)
	{
		LLPreviewGesture* self = (LLPreviewGesture*)preview;

		if (0 == status)
		{
			LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
			S32 size = file.getSize();

			std::vector<char> buffer(size+1);
			file.read((U8*)&buffer[0], size);
			buffer[size] = '\0';

			LLMultiGesture* gesture = new LLMultiGesture();

			LLDataPackerAsciiBuffer dp(&buffer[0], size+1);
			BOOL ok = gesture->deserialize(dp);

			if (ok)
			{
				// Everything has been successful.  Load up the UI.
				self->loadUIFromGesture(gesture);

				self->mStepList->selectFirstItem();

				self->mDirty = FALSE;
				self->refresh();
				self->refreshFromItem(self->getItem()); // to update description and title
			}
			else
			{
				llwarns << "Unable to load gesture" << llendl;
			}

			delete gesture;
			gesture = NULL;

			self->mAssetStatus = PREVIEW_ASSET_LOADED;
		}
		else
		{
			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );

			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
				LL_ERR_FILE_EMPTY == status)
			{
				LLDelayedGestureError::gestureMissing( *item_idp );
			}
			else
			{
				LLDelayedGestureError::gestureFailedToLoad( *item_idp );
			}

			llwarns << "Problem loading gesture: " << status << llendl;
			self->mAssetStatus = PREVIEW_ASSET_ERROR;
		}
	}
	delete item_idp;
	item_idp = NULL;
}
void LLPreviewGesture::saveIfNeeded()
{
	if (!gAssetStorage)
	{
		llwarns << "Can't save gesture, no asset storage system." << llendl;
		return;
	}

	if (!mDirty)
	{
		return;
	}

	// Copy the UI into a gesture
	LLMultiGesture* gesture = createGesture();

	// Serialize the gesture
	S32 max_size = gesture->getMaxSerialSize();
	char* buffer = new char[max_size];

	LLDataPackerAsciiBuffer dp(buffer, max_size);

	BOOL ok = gesture->serialize(dp);

	// <edit>
	//if (dp.getCurrentSize() > 1000)
	if(0)
	// </edit>
	{
		LLNotificationsUtil::add("GestureSaveFailedTooManySteps");

		delete gesture;
		gesture = NULL;
	}
	else if (!ok)
	{
		LLNotificationsUtil::add("GestureSaveFailedTryAgain");
		delete gesture;
		gesture = NULL;
	}
	else
	{
		// Every save gets a new UUID.  Yup.
		LLTransactionID tid;
		LLAssetID asset_id;
		tid.generate();
		asset_id = tid.makeAssetID(gAgent.getSecureSessionID());

		LLVFile file(gVFS, asset_id, LLAssetType::AT_GESTURE, LLVFile::APPEND);

		S32 size = dp.getCurrentSize();
		file.setMaxSize(size);
		file.write((U8*)buffer, size);

		BOOL delayedUpload = FALSE;

		// Upload that asset to the database
		LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem();
		if (item)
		{
			std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
			std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory");
			if (mObjectUUID.isNull() && !agent_url.empty())
			{
				//need to disable the preview floater so item
				//isn't re-saved before new asset arrives
				//fake out refresh.
				item->setComplete(FALSE);
				refresh();				
				item->setComplete(TRUE);

				// Saving into agent inventory
				LLSD body;
				body["item_id"] = mItemUUID;
				LLHTTPClient::post(agent_url, body,
					new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
				delayedUpload = TRUE;
			}
			else if (!mObjectUUID.isNull() && !task_url.empty())
			{
				// Saving into task inventory
				LLSD body;
				body["task_id"] = mObjectUUID;
				body["item_id"] = mItemUUID;
				LLHTTPClient::post(task_url, body,
					new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
			}
			else if (gAssetStorage)
			{
				LLLineEditor* descEditor = getChild<LLLineEditor>("desc");
				LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid);
				gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE);
			}
		}

		// If this gesture is active, then we need to update the in-memory
		// active map with the new pointer.
		if (!delayedUpload && LLGestureMgr::instance().isGestureActive(mItemUUID))
		{
			// gesture manager now owns the pointer
			LLGestureMgr::instance().replaceGesture(mItemUUID, gesture, asset_id);

			// replaceGesture may deactivate other gestures so let the
			// inventory know.
			gInventory.notifyObservers();
		}
		else
		{
			// we're done with this gesture
			delete gesture;
			gesture = NULL;
		}

		mDirty = FALSE;
		// refresh will be called when callback
		// if triggered when delayedUpload
		if(!delayedUpload)
		{
			refresh();
		}
	}

	delete [] buffer;
	buffer = NULL;
}
BOOL LLGestureMgr::matchPrefix(const std::string& in_str, std::string* out_str)
{
	S32 in_len = in_str.length();

#ifdef MATCH_COMMON_CHARS
	std::string rest_of_match = "";
	std::string buf = "";
#endif
	item_map_t::iterator it;
	for (it = mActive.begin(); it != mActive.end(); ++it)
	{
		LLMultiGesture* gesture = (*it).second;
		if (gesture)
		{
			const std::string& trigger = gesture->getTrigger();
#ifdef MATCH_COMMON_CHARS
			//return whole trigger, if received text equals to it
			if (!LLStringUtil::compareInsensitive(in_str, trigger))
			{
				*out_str = trigger;
				return TRUE;
			}
#else
			if (in_len > (S32)trigger.length()) continue; 	// too short, bail out
#endif

			//return common chars, if more than one trigger matches the prefix
			std::string trigger_trunc = trigger;
			LLStringUtil::truncate(trigger_trunc, in_len);
			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
			{
#ifndef MATCH_COMMON_CHARS
				*out_str = trigger;
				return TRUE;
#else
				if (rest_of_match.compare("") == 0)
				{
					rest_of_match = trigger.substr(in_str.size());
				}
				std::string cur_rest_of_match = trigger.substr(in_str.size());
				buf = "";
				U32 i=0;

				while (i<rest_of_match.length() && i<cur_rest_of_match.length())
				{
					if (rest_of_match[i]==cur_rest_of_match[i])
					{
						buf.push_back(rest_of_match[i]);
					}
					else
					{
						if (i==0)
						{
							rest_of_match = "";
						}
						break;
					}
					i++;
				}
				if (rest_of_match.compare("") == 0)
				{
					return FALSE;
				}
				if (buf.compare("") != 0)
				{
					rest_of_match = buf;
				}
#endif
			}
		}
	}

#ifdef MATCH_COMMON_CHARS
	if (!rest_of_match.empty())
	{
		*out_str = in_str + rest_of_match;
		return TRUE;
	}
#endif

	return FALSE;
}
// static
void LLGestureMgr::onLoadComplete(LLVFS *vfs,
									   const LLUUID& asset_uuid,
									   LLAssetType::EType type,
									   void* user_data, S32 status, LLExtStat ext_status)
{
	LLLoadInfo* info = (LLLoadInfo*)user_data;

	LLUUID item_id = info->mItemID;
	BOOL inform_server = info->mInformServer;
	BOOL deactivate_similar = info->mDeactivateSimilar;

	delete info;
	info = NULL;
	LLGestureMgr& self = LLGestureMgr::instance();
	self.mLoadingCount--;

	if (0 == status)
	{
		LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
		S32 size = file.getSize();

		char* buffer = new char[size+1];
		if (buffer == NULL)
		{
			LL_ERRS() << "Memory Allocation Failed" << LL_ENDL;
			return;
		}

		file.read((U8*)buffer, size);		/* Flawfinder: ignore */
		// ensure there's a trailing NULL so strlen will work.
		buffer[size] = '\0';

		LLMultiGesture* gesture = new LLMultiGesture();

		LLDataPackerAsciiBuffer dp(buffer, size+1);
		BOOL ok = gesture->deserialize(dp);

		if (ok)
		{
			if (deactivate_similar)
			{
				self.deactivateSimilarGestures(gesture, item_id);

				// Display deactivation message if this was the last of the bunch.
				if (self.mLoadingCount == 0
					&& self.mDeactivateSimilarNames.length() > 0)
				{
					// we're done with this set of deactivations
					LLSD args;
					args["NAMES"] = self.mDeactivateSimilarNames;
					LLNotificationsUtil::add("DeactivatedGesturesTrigger", args);
				}
			}

			LLViewerInventoryItem* item = gInventory.getItem(item_id);
			if(item)
			{
				gesture->mName = item->getName();
			}
			else
			{
				// Watch this item and set gesture name when item exists in inventory
				self.setFetchID(item_id);
				self.startFetch();
			}
			self.mActive[item_id] = gesture;

			// Everything has been successful.  Add to the active list.
			gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);

			if (inform_server)
			{
				// Inform the database of this change
				LLMessageSystem* msg = gMessageSystem;
				msg->newMessage("ActivateGestures");
				msg->nextBlock("AgentData");
				msg->addUUID("AgentID", gAgent.getID());
				msg->addUUID("SessionID", gAgent.getSessionID());
				msg->addU32("Flags", 0x0);
				
				msg->nextBlock("Data");
				msg->addUUID("ItemID", item_id);
				msg->addUUID("AssetID", asset_uuid);
				msg->addU32("GestureFlags", 0x0);

				gAgent.sendReliableMessage();
			}
			callback_map_t::iterator i_cb = self.mCallbackMap.find(item_id);
			
			if(i_cb != self.mCallbackMap.end())
			{
				i_cb->second(gesture);
				self.mCallbackMap.erase(i_cb);
			}

			self.notifyObservers();
		}
		else
		{
			LL_WARNS() << "Unable to load gesture" << LL_ENDL;

			self.mActive.erase(item_id);
			
			delete gesture;
			gesture = NULL;
		}

		delete [] buffer;
		buffer = NULL;
	}
	else
	{
		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );

		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
			LL_ERR_FILE_EMPTY == status)
		{
			LLDelayedGestureError::gestureMissing( item_id );
		}
		else
		{
			LLDelayedGestureError::gestureFailedToLoad( item_id );
		}

		LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL;
		
		LLGestureMgr::instance().mActive.erase(item_id);			
	}
}
Example #9
0
// static
void LLGestureManager::onLoadComplete(LLVFS *vfs,
									   const LLUUID& asset_uuid,
									   LLAssetType::EType type,
									   void* user_data, S32 status, LLExtStat ext_status)
{
	LLLoadInfo* info = (LLLoadInfo*)user_data;

	LLUUID item_id = info->mItemID;
	BOOL inform_server = info->mInformServer;
	BOOL deactivate_similar = info->mDeactivateSimilar;

	delete info;
	info = NULL;

	gGestureManager.mLoadingCount--;

	if (0 == status)
	{
		LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
		S32 size = file.getSize();

		char* buffer = new char[size+1];
		if (buffer == NULL)
		{
			llerrs << "Memory Allocation Failed" << llendl;
			return;
		}

		file.read((U8*)buffer, size);		/* Flawfinder: ignore */
		// ensure there's a trailing NULL so strlen will work.
		buffer[size] = '\0';

		LLMultiGesture* gesture = new LLMultiGesture();

		LLDataPackerAsciiBuffer dp(buffer, size+1);
		BOOL ok = gesture->deserialize(dp);

		if (ok)
		{
			if (deactivate_similar)
			{
				gGestureManager.deactivateSimilarGestures(gesture, item_id);

				// Display deactivation message if this was the last of the bunch.
				if (gGestureManager.mLoadingCount == 0
					&& gGestureManager.mDeactivateSimilarNames.length() > 0)
				{
					// we're done with this set of deactivations
					LLStringUtil::format_map_t args;
					args["[NAMES]"] = gGestureManager.mDeactivateSimilarNames;
					LLNotifyBox::showXml("DeactivatedGesturesTrigger", args);
				}
			}

			// Everything has been successful.  Add to the active list.
			gGestureManager.mActive[item_id] = gesture;
			gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
			if (inform_server)
			{
				// Inform the database of this change
				LLMessageSystem* msg = gMessageSystem;
				msg->newMessage("ActivateGestures");
				msg->nextBlock("AgentData");
				msg->addUUID("AgentID", gAgent.getID());
				msg->addUUID("SessionID", gAgent.getSessionID());
				msg->addU32("Flags", 0x0);
				
				msg->nextBlock("Data");
				msg->addUUID("ItemID", item_id);
				msg->addUUID("AssetID", asset_uuid);
				msg->addU32("GestureFlags", 0x0);

				gAgent.sendReliableMessage();
			}

			gGestureManager.notifyObservers();
		}
		else
		{
			llwarns << "Unable to load gesture" << llendl;

			gGestureManager.mActive.erase(item_id);
			
			delete gesture;
			gesture = NULL;
		}

		delete [] buffer;
		buffer = NULL;
	}
	else
	{
		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );

		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
			LL_ERR_FILE_EMPTY == status)
		{
			LLDelayedGestureError::gestureMissing( item_id );
		}
		else
		{
			LLDelayedGestureError::gestureFailedToLoad( item_id );
		}

		llwarns << "Problem loading gesture: " << status << llendl;
		
		gGestureManager.mActive.erase(item_id);			
	}
}