diff options
| author | Josh Bell <josh@lindenlab.com> | 2007-03-14 23:03:50 +0000 | 
|---|---|---|
| committer | Josh Bell <josh@lindenlab.com> | 2007-03-14 23:03:50 +0000 | 
| commit | 00dbacb215da8d6b6739b4bcefebee552de89a9c (patch) | |
| tree | e1256e1fa3b195a1128bb152a876729c7f9a163d /indra/newview | |
| parent | cf405184285c25723249d5a023b28d9498cf0c3f (diff) | |
svn merge svn+ssh://svn.lindenlab.com/svn/linden/release@59161 svn+ssh://svn.lindenlab.com/svn/linden/branches/release-candidate@59163 --> release
Diffstat (limited to 'indra/newview')
25 files changed, 1309 insertions, 596 deletions
| diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 66ce415541..f49ffa1603 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -1,5 +1,5 @@  /* Localized versions of Info.plist keys */  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 1.13.3.3"; -CFBundleGetInfoString = "Second Life version 1.13.3.3, Copyright 2004-2006 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 1.13.4.8"; +CFBundleGetInfoString = "Second Life version 1.13.4.8, Copyright 2004-2007 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 13901656b5..448c7922ff 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>1.13.3.3</string> +	<string>1.13.4.8</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index b37538f023..7c615dd159 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -1,10 +1,6 @@ -/**  - * @file llmapresponders.h - * @brief Processes responses received for asset upload requests. - * - * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc. - * $License$ - */ +// llassetuploadresponders.cpp +// Copyright 2006, Linden Research, Inc. +// Processes responses received for asset upload requests.  #include "llviewerprecompiledheaders.h" @@ -19,39 +15,71 @@  #include "llinventorymodel.h"  #include "llinventoryview.h"  #include "llpermissionsflags.h" +#include "llpreviewnotecard.h" +#include "llpreviewscript.h" +#include "llscrolllistctrl.h"  #include "lluploaddialog.h" -#include "llviewermenu.h"	// for upload_new_resource() +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llviewermenu.h"  #include "llviewerwindow.h"  #include "viewer.h" -LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLUUID& uuid, -														   const LLSD &post_data) -	: LLHTTPClient::Responder() +void dialog_refresh_all(); + +LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, +											   const LLUUID& vfile_id, +											   LLAssetType::EType asset_type) +	: LLHTTPClient::Responder(), +	  mPostData(post_data), +	  mVFileID(vfile_id), +	  mAssetType(asset_type) +{ +	if (!gVFS->getExists(vfile_id, asset_type)) +	{ +		llwarns << "LLAssetUploadResponder called with nonexistant vfile_id" << llendl; +		mVFileID.setNull(); +		mAssetType = LLAssetType::AT_NONE; +		return; +	} +} + +LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, +											   const std::string& file_name) +	: LLHTTPClient::Responder(), +	  mPostData(post_data), +	  mFileName(file_name) +{ +} + +LLAssetUploadResponder::~LLAssetUploadResponder()  { -	mUUID = uuid; -	mPostData = post_data; +	if (!mFileName.empty()) +	{ +		// Delete temp file +		LLFile::remove(mFileName.c_str()); +	}  }  // virtual -void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason) +void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)  { -	llinfos << "LLNewAgentInventoryResponder::error " << statusNum << llendl; +	llinfos << "LLAssetUploadResponder::error " << statusNum  +			<< " reason: " << reason << llendl;  	LLStringBase<char>::format_map_t args;  	switch(statusNum)  	{  		case 400: -			args["[FILE]"] = mPostData["inventory_type"].asString(); -			args["[REASON]"] = "invalid parameters in upload request"; +			args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName); +			args["[REASON]"] = "Error in upload request.  Please contact " +				"support@lindenlab.com for help fixing this problem.";  			gViewerWindow->alertXml("CannotUploadReason", args);  			break; -		case 402: -			//(result["message"].asString() == "insufficient funds") -			LLFloaterBuyCurrency::buyCurrency("Uploading costs", gGlobalEconomy->getPriceUpload()); -			break;  		case 500:  		default: -			args["[FILE]"] = mPostData["inventory_type"].asString(); -			args["[REASON]"] = "the server is experiencing unexpected difficulties"; +			args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName); +			args["[REASON]"] = "The server is experiencing unexpected " +				"difficulties. Please try again later.";  			gViewerWindow->alertXml("CannotUploadReason", args);  			break;  	} @@ -59,139 +87,373 @@ void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reaso  }  //virtual  -void LLNewAgentInventoryResponder::result(const LLSD& result) +void LLAssetUploadResponder::result(const LLSD& content)  { -	lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; +	lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl; -	if (!result["success"]) +	std::string state = content["state"]; +	if (state == "upload") +	{ +		uploadUpload(content); +	} +	else if (state == "complete") +	{ +		// rename file in VFS with new asset id +		if (mFileName.empty()) +		{ +			// rename the file in the VFS to the actual asset id +			gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType); +		} +		uploadComplete(content); +	} +	else +	{ +		uploadFailure(content); +	} +} + +void LLAssetUploadResponder::uploadUpload(const LLSD& content) +{ +	std::string uploader = content["uploader"]; +	if (mFileName.empty()) +	{ +		LLHTTPClient::postFile(uploader, mVFileID, mAssetType, this); +	} +	else +	{ +		LLHTTPClient::postFile(uploader, mFileName, this); +	}
 +} + +void LLAssetUploadResponder::uploadFailure(const LLSD& content) +{ +	std::string reason = content["state"]; +	// deal with money errors +	if (reason == "insufficient funds") +	{ +		LLFloaterBuyCurrency::buyCurrency("Uploading costs", gGlobalEconomy->getPriceUpload()); +	} +	else  	{  		LLStringBase<char>::format_map_t args; -		args["[FILE]"] = mPostData["inventory_type"].asString(); -		args["[REASON]"] = "the server is experiencing unexpected difficulties"; +		args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName); +		args["[REASON]"] = content["message"].asString();  		gViewerWindow->alertXml("CannotUploadReason", args); -		return;  	} +} + +void LLAssetUploadResponder::uploadComplete(const LLSD& content) +{ +} + +LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, +														   const LLUUID& vfile_id, +														   LLAssetType::EType asset_type) +: LLAssetUploadResponder(post_data, vfile_id, asset_type) +{ +} + +LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name) +: LLAssetUploadResponder(post_data, file_name) +{ +} + +//virtual  +void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) +{ +	lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; -	std::string uploader = result["uploader"];  	LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString().c_str());  	LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString().c_str()); -	// request succeeded -	if (!uploader.empty()) + +	// Update money and ownership credit information +	// since it probably changed on the server +	if (asset_type == LLAssetType::AT_TEXTURE || +		asset_type == LLAssetType::AT_SOUND || +		asset_type == LLAssetType::AT_ANIMATION)  	{ -		LLHTTPClient::postFile(uploader, mUUID, asset_type, this); +		gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); +		gMessageSystem->nextBlockFast(_PREHASH_AgentData); +		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +		gMessageSystem->nextBlockFast(_PREHASH_MoneyData); +		gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); +		gAgent.sendReliableMessage(); + +		LLString::format_map_t args; +		args["[AMOUNT]"] = llformat("%d",gGlobalEconomy->getPriceUpload()); +		LLNotifyBox::showXml("UploadPayment", args);  	} -	// upload succeeded -	else -	{ -		// rename the file in the VFS to the actual asset id -		gVFS->renameFile(mUUID, asset_type, result["new_asset"].asUUID(), asset_type); -		// TODO: only request for textures, sound, and animation uploads -		// Update money and ownership credit information -		// since it probably changed on the server -		if (mPostData["asset_type"].asString() == "texture" ||  -			mPostData["asset_type"].asString() == "sound" || -			mPostData["asset_type"].asString() == "animatn") +	// Actually add the upload to viewer inventory +	llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " +			<< content["new_asset"].asUUID() << " to inventory." << llendl; +	if(mPostData["folder_id"].asUUID().notNull()) +	{ +		LLPermissions perm; +		U32 next_owner_perm; +		perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); +		if (mPostData["inventory_type"].asString() == "snapshot")  		{ -			gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); -			gMessageSystem->nextBlockFast(_PREHASH_AgentData); -			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -			gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -			gMessageSystem->nextBlockFast(_PREHASH_MoneyData); -			gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); -			gAgent.sendReliableMessage(); - -			LLString::format_map_t args; -			args["[AMOUNT]"] = llformat("%d",gGlobalEconomy->getPriceUpload()); -			LLNotifyBox::showXml("UploadPayment", args); +			next_owner_perm = PERM_ALL;  		} -		// Actually add the upload to viewer inventory -		llinfos << "Adding " << result["new_inventory_item"].asUUID() << " " -				<< result["new_asset"].asUUID() << " to inventory." << llendl; -		if(mPostData["folder_id"].asUUID().notNull()) +		else  		{ -			LLPermissions perm; -			U32 next_owner_perm; -			perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); -			if (mPostData["inventory_type"].asString() == "snapshot") +			next_owner_perm = PERM_MOVE | PERM_TRANSFER; +		} +		perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); +		S32 creation_date_now = time_corrected(); +		LLPointer<LLViewerInventoryItem> item +			= new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), +										mPostData["folder_id"].asUUID(), +										perm, +										content["new_asset"].asUUID(), +										asset_type, +										inventory_type, +										mPostData["name"].asString(), +										mPostData["description"].asString(), +										LLSaleInfo::DEFAULT, +										LLInventoryItem::II_FLAGS_NONE, +										creation_date_now); +		gInventory.updateItem(item); +		gInventory.notifyObservers(); + +		// Show the preview panel for textures and sounds to let +		// user know that the image (or snapshot) arrived intact. +		LLInventoryView* view = LLInventoryView::getActiveInventory(); +		if(view) +		{ +			LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); +			LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback(); + +			view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); +			if((LLAssetType::AT_TEXTURE == asset_type) +				|| (LLAssetType::AT_SOUND == asset_type))  			{ -				next_owner_perm = PERM_ALL; +				view->getPanel()->openSelected();  			} -			else +			//LLInventoryView::dumpSelectionInformation((void*)view); +			// restore keyboard focus +			gFocusMgr.setKeyboardFocus(focus_ctrl, callback); +		} +	} +	else +	{ +		llwarns << "Can't find a folder to put it in" << llendl; +	} + +	// remove the "Uploading..." message +	LLUploadDialog::modalUploadFinished(); +	 +	// *FIX: This is a pretty big hack. What this does is check the +	// file picker if there are any more pending uploads. If so, +	// upload that file. +	const char* next_file = LLFilePicker::instance().getNextFile(); +	if(next_file) +	{ +		const char* name = LLFilePicker::instance().getDirname(); + +		LLString asset_name = name; +		LLString::replaceNonstandardASCII( asset_name, '?' ); +		LLString::replaceChar(asset_name, '|', '?'); +		LLString::stripNonprintable(asset_name); +		LLString::trim(asset_name); + +		char* asset_name_str = (char*)asset_name.c_str(); +		char* end_p = strrchr(asset_name_str, '.');		 // strip extension if exists +		if( !end_p ) +		{ +			 end_p = asset_name_str + strlen( asset_name_str );			/*Flawfinder: ignore*/ +		} +			 +		S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); + +		asset_name = asset_name.substr( 0, len ); + +		upload_new_resource(next_file, asset_name, asset_name, +							0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); +	} +} + + +LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data, +																 const LLUUID& vfile_id, +																 LLAssetType::EType asset_type) +: LLAssetUploadResponder(post_data, vfile_id, asset_type) +{ +} + +LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data, +																 const std::string& file_name) +: LLAssetUploadResponder(post_data, file_name) +{ +} + +//virtual  +void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) +{ +	llinfos << "LLUpdateAgentInventoryResponder::result from capabilities" << llendl; +	LLUUID item_id = mPostData["item_id"]; + +	LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(item_id); +	if(!item) +	{ +		llwarns << "Inventory item for " << mVFileID +			<< " is no longer in agent inventory." << llendl; +		return; +	} + +	// Update viewer inventory item +	LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); +	new_item->setAssetUUID(content["new_asset"].asUUID()); +	gInventory.updateItem(new_item); +	gInventory.notifyObservers(); + +	llinfos << "Inventory item " << item->getName() << " saved into " +		<< content["new_asset"].asString() << llendl; + +	LLInventoryType::EType inventory_type = new_item->getInventoryType(); +	switch(inventory_type) +	{ +		case LLInventoryType::IT_NOTECARD:  			{ -				next_owner_perm = PERM_MOVE | PERM_TRANSFER; + +				// Update the UI with the new asset. +				LLPreviewNotecard* nc; +				nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID()); +				if(nc) +				{ +					// *HACK: we have to delete the asset in the VFS so +					// that the viewer will redownload it. This is only +					// really necessary if the asset had to be modified by +					// the uploader, so this can be optimized away in some +					// cases. A better design is to have a new uuid if the +					// script actually changed the asset. +					if(nc->hasEmbeddedInventory()) +					{ +						gVFS->removeFile( +							content["new_asset"].asUUID(), +							LLAssetType::AT_NOTECARD); +					} +					nc->refreshFromInventory(); +				}  			} -			perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); -			S32 creation_date_now = time_corrected(); -			LLPointer<LLViewerInventoryItem> item -				= new LLViewerInventoryItem(result["new_inventory_item"].asUUID(), -											mPostData["folder_id"].asUUID(), -											perm, -											result["new_asset"].asUUID(), -											asset_type, -											inventory_type, -											mPostData["name"].asString(), -											mPostData["description"].asString(), -											LLSaleInfo::DEFAULT, -											LLInventoryItem::II_FLAGS_NONE, -											creation_date_now); -			gInventory.updateItem(item); -			gInventory.notifyObservers(); - -			// Show the preview panel for textures and sounds to let -			// user know that the image (or snapshot) arrived intact. -			LLInventoryView* view = LLInventoryView::getActiveInventory(); -			if(view) +			break; +		case LLInventoryType::IT_LSL:  			{ -				LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); -				LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback(); - -				view->getPanel()->setSelection(result["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); -				if((LLAssetType::AT_TEXTURE == asset_type) -					|| (LLAssetType::AT_SOUND == asset_type)) +				// Find our window and close it if requested. +				LLPreviewLSL* preview = (LLPreviewLSL*)LLPreview::find(item_id); +				if (preview)  				{ -					view->getPanel()->openSelected(); +					// Bytecode save completed +					if (content["compiled"]) +					{ +						preview->callbackLSLCompileSucceeded(); +					} +					else +					{ +						preview->callbackLSLCompileFailed(content["errors"]); +					}  				} -				//LLInventoryView::dumpSelectionInformation((void*)view); -				// restore keyboard focus -				gFocusMgr.setKeyboardFocus(focus_ctrl, callback);  			} -		} -		else -		{ -			llwarns << "Can't find a folder to put it in" << llendl; -		} +			break; +		case LLInventoryType::IT_WEARABLE: +		default: +			break; +	} +} -		// remove the "Uploading..." message -		LLUploadDialog::modalUploadFinished(); -		 -		// *NOTE: This is a pretty big hack. What this does is check -		// the file picker if there are any more pending uploads. If -		// so, upload that file. -		const char* next_file = LLFilePicker::instance().getNextFile(); -		if(next_file) -		{ -			const char* name = LLFilePicker::instance().getDirname(); -			LLString asset_name = name; -			LLString::replaceNonstandardASCII( asset_name, '?' ); -			LLString::replaceChar(asset_name, '|', '?'); -			LLString::stripNonprintable(asset_name); -			LLString::trim(asset_name); +LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data, +																 const LLUUID& vfile_id, +																 LLAssetType::EType asset_type) +: LLAssetUploadResponder(post_data, vfile_id, asset_type) +{ +} -			char* asset_name_str = (char*)asset_name.c_str(); -			char* end_p = strrchr(asset_name_str, '.');		 // strip extension if exists -			if( !end_p ) +LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data, +															   const std::string& file_name) +: LLAssetUploadResponder(post_data, file_name) +{ +} + +//virtual  +void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) +{ +	llinfos << "LLUpdateTaskInventoryResponder::result from capabilities" << llendl; +	LLUUID item_id = mPostData["item_id"]; +	LLUUID task_id = mPostData["task_id"]; + +	LLViewerObject* object = gObjectList.findObject(task_id); +	if (!object) +	{ +		llwarns << "LLUpdateTaskInventoryResponder::uploadComplete task " << task_id +			<< " no longer exist." << llendl; +		return; +	} +	LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(item_id); +	if (!item) +	{ +		llwarns << "LLUpdateTaskInventoryResponder::uploadComplete item " +			<< item_id << " is no longer in task " << task_id +			<< "'s inventory." << llendl; +		return; +	} +	LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); +	// Update Viewer inventory +	object->updateViewerInventoryAsset(new_item, content["new_asset"]); +	dialog_refresh_all(); +	 +	LLInventoryType::EType inventory_type = new_item->getInventoryType(); +	switch(inventory_type) +	{ +		case LLInventoryType::IT_NOTECARD:  			{ -				end_p = asset_name_str + strlen( asset_name_str );			/*Flawfinder: ignore*/ -			} -				 -			S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); -			asset_name = asset_name.substr( 0, len ); +				// Update the UI with the new asset. +				LLPreviewNotecard* nc; +				nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID()); +				if(nc) +				{ +					// *HACK: we have to delete the asset in the VFS so +					// that the viewer will redownload it. This is only +					// really necessary if the asset had to be modified by +					// the uploader, so this can be optimized away in some +					// cases. A better design is to have a new uuid if the +					// script actually changed the asset. +					if(nc->hasEmbeddedInventory()) +					{ +						gVFS->removeFile( +							content["new_asset"].asUUID(), +							LLAssetType::AT_NOTECARD); +					} -			upload_new_resource(next_file, asset_name, asset_name, -								0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); -		} +					nc->refreshFromInventory(); +				} +			} +			break; +		case LLInventoryType::IT_LSL: +			{ +				LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id); +				if (preview) +				{ +					// Bytecode save completed +					if (content["compiled"]) +					{ +						preview->callbackLSLCompileSucceeded( +							task_id, +							item_id, +							mPostData["is_script_running"]); +					} +					else +					{ +						preview->callbackLSLCompileFailed(content["errors"]); +					} +				} +			} +			break; +		case LLInventoryType::IT_WEARABLE: +		default: +			break;  	}  } diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index b4d5377601..ef8cd3834a 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -1,26 +1,65 @@ -/**  - * @file llmapresponders.h - * @brief Processes responses received for asset upload requests. - * - * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc. - * $License$ - */ +// llassetuploadresponders.h +// Copyright 2006, Linden Research, Inc. +// Processes responses received for asset upload requests. -#ifndef LL_LLNEWAGENTINVENTORYRESPONDER_H -#define LL_LLNEWAGENTINVENTORYRESPONDER_H +#ifndef LL_LLASSETUPLOADRESPONDER_H +#define LL_LLASSETUPLOADRESPONDER_H  #include "llhttpclient.h" -class LLNewAgentInventoryResponder : public LLHTTPClient::Responder +// Abstract class for supporting asset upload +// via capabilities +class LLAssetUploadResponder : public LLHTTPClient::Responder  {  public: -	LLNewAgentInventoryResponder(const LLUUID& uuid, const LLSD& post_data); -    void error(U32 statusNum, const std::string& reason); +	LLAssetUploadResponder(const LLSD& post_data, +							const LLUUID& vfile_id, +							LLAssetType::EType asset_type); +	LLAssetUploadResponder(const LLSD& post_data, const std::string& file_name); +	~LLAssetUploadResponder(); +    virtual void error(U32 statusNum, const std::string& reason);  	virtual void result(const LLSD& content); +	virtual void uploadUpload(const LLSD& content); +	virtual void uploadComplete(const LLSD& content); +	virtual void uploadFailure(const LLSD& content); -private: -	LLUUID mUUID; +protected:  	LLSD mPostData; +	LLUUID mVFileID; +	LLAssetType::EType mAssetType; +	std::string mFileName;  }; -#endif // LL_LLNEWAGENTINVENTORYRESPONDER_H +class LLNewAgentInventoryResponder : public LLAssetUploadResponder +{ +public: +	LLNewAgentInventoryResponder(const LLSD& post_data, +								const LLUUID& vfile_id, +								LLAssetType::EType asset_type); +	LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name); +	virtual void uploadComplete(const LLSD& content); +}; + +class LLUpdateAgentInventoryResponder : public LLAssetUploadResponder +{ +public: +	LLUpdateAgentInventoryResponder(const LLSD& post_data, +								const LLUUID& vfile_id, +								LLAssetType::EType asset_type); +	LLUpdateAgentInventoryResponder(const LLSD& post_data, +								const std::string& file_name); +	virtual void uploadComplete(const LLSD& content); +}; + +class LLUpdateTaskInventoryResponder : public LLAssetUploadResponder +{ +public: +	LLUpdateTaskInventoryResponder(const LLSD& post_data, +								const LLUUID& vfile_id, +								LLAssetType::EType asset_type); +	LLUpdateTaskInventoryResponder(const LLSD& post_data, +								const std::string& file_name); +	virtual void uploadComplete(const LLSD& content); +}; + +#endif // LL_LLASSETUPLOADRESPONDER_H diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index f82978c5fc..7eaac8887c 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -39,6 +39,8 @@  #include "llvfs.h"  #include "viewer.h" +#include "llassetuploadresponders.h" +  ///----------------------------------------------------------------------------  /// Local function declarations, constants, enums, and typedefs  ///---------------------------------------------------------------------------- @@ -206,6 +208,23 @@ void LLFloaterPostcard::onClickCancel(void* data)  	}  } +class LLSendPostcardResponder : public LLAssetUploadResponder +{ +public: +	LLSendPostcardResponder(const LLSD &post_data, +							const LLUUID& vfile_id, +							LLAssetType::EType asset_type): +	    LLAssetUploadResponder(post_data, vfile_id, asset_type) +	{	 +	} +	// *TODO define custom uploadFailed here so it's not such a generic message +	void LLSendPostcardResponder::uploadComplete(const LLSD& content) +	{ +		// we don't care about what the server returns from this post, just clean up the UI +		LLUploadDialog::modalUploadFinished(); +	} +}; +  // static  void LLFloaterPostcard::onClickSend(void* data)  { @@ -230,12 +249,31 @@ void LLFloaterPostcard::onClickSend(void* data)  		if (self->mJPEGImage.notNull())  		{ -			// upload the image  			self->mTransactionID.generate();  			self->mAssetID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID());  			LLVFile::writeFile(self->mJPEGImage->getData(), self->mJPEGImage->getDataSize(), gVFS, self->mAssetID, LLAssetType::AT_IMAGE_JPEG); -			 -			gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)self, FALSE); + +			// upload the image +			std::string url = gAgent.getRegion()->getCapability("SendPostcard"); +			if(!url.empty()) +			{ +				llinfos << "Send Postcard via capability" << llendl; +				LLSD body = LLSD::emptyMap(); +				// the capability already encodes: agent ID, region ID +				body["pos-global"] = self->mPosTakenGlobal.getValue(); +				body["to"] = self->childGetValue("to_form").asString(); +				body["from"] = self->childGetValue("from_form").asString(); +				body["name"] = self->childGetValue("name_form").asString(); +				body["subject"] = self->childGetValue("subject_form").asString(); +				body["msg"] = self->childGetValue("msg_form").asString(); +				body["allow-publish"] = self->childGetValue("allow_publish_check").asBoolean(); +				body["mature-publish"] = self->childGetValue("mature_check").asBoolean(); +				LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, self->mAssetID, LLAssetType::AT_IMAGE_JPEG)); +			}  +			else +			{ +				gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)self, FALSE); +			}  			LLUploadDialog::modalUploadDialog("Uploading...\n\nPostcard"); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 84c99db8da..62f5fd21d5 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -44,6 +44,7 @@  #include "lltooldraganddrop.h"  #include "llfloatermap.h"  #include "lluiconstants.h" +#include "lluploaddialog.h"  #include "llcallingcard.h"  #include "llviewerobjectlist.h"  #include "llagent.h" @@ -61,6 +62,7 @@  #include "llvieweruictrlfactory.h"  #include "viewer.h" +#include "llassetuploadresponders.h"  const U32 INCLUDE_SCREENSHOT  = 0x01 << 0; @@ -96,7 +98,8 @@ LLFloaterReporter::LLFloaterReporter(  	mDeselectOnClose( FALSE ),  	mPicking( FALSE),   	mPosition(), -	mCopyrightWarningSeen( FALSE ) +	mCopyrightWarningSeen( FALSE ), +	mResourceDatap(new LLResourceData())  {  	if (report_type == BUG_REPORT)  	{ @@ -147,9 +150,9 @@ LLFloaterReporter::LLFloaterReporter(  	gReporterInstances.addData(report_type, this); -	// Upload a screenshot, but don't draw this floater. +	// Take a screenshot, but don't draw this floater.  	setVisible(FALSE); -	uploadScreenshot(); +	takeScreenshot();  	setVisible(TRUE);  	// Default text to be blank @@ -211,6 +214,7 @@ LLFloaterReporter::~LLFloaterReporter()  	std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );  	mMCDList.clear(); +	delete mResourceDatap;  	gDialogVisible = FALSE;  } @@ -344,7 +348,7 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,  	if ( self->mReportType != BUG_REPORT )  	{  		self->childSetText("abuser_name_edit", names[0] ); - +		  		self->mAbuserID = ids[0];  		self->refresh(); @@ -355,31 +359,59 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,  void LLFloaterReporter::onClickSend(void *userdata)  {  	LLFloaterReporter *self = (LLFloaterReporter *)userdata; +	 +	if (self->mPicking) +	{ +		closePickTool(self); +	} -	// only do this for abuse reports -	if ( self->mReportType != BUG_REPORT ) +	if(self->validateReport())  	{ -		if ( ! self->mCopyrightWarningSeen ) +		// only show copyright alert for abuse reports +		if ( self->mReportType != BUG_REPORT )  		{ -			LLString details_lc = self->childGetText("details_edit"); -			LLString::toLower( details_lc ); -			LLString summary_lc = self->childGetText("summary_edit"); -			LLString::toLower( summary_lc ); -			if ( details_lc.find( "copyright" ) != std::string::npos || -				summary_lc.find( "copyright" ) != std::string::npos ) +			if ( ! self->mCopyrightWarningSeen )  			{ -				gViewerWindow->alertXml("HelpReportAbuseContainsCopyright"); -				self->mCopyrightWarningSeen = TRUE; -				return; +				LLString details_lc = self->childGetText("details_edit"); +				LLString::toLower( details_lc ); +				LLString summary_lc = self->childGetText("summary_edit"); +				LLString::toLower( summary_lc ); +				if ( details_lc.find( "copyright" ) != std::string::npos || +					summary_lc.find( "copyright" ) != std::string::npos ) +				{ +					gViewerWindow->alertXml("HelpReportAbuseContainsCopyright"); +					self->mCopyrightWarningSeen = TRUE; +					return; +				};  			};  		}; -	}; -	if (self->mPicking) -	{ -		closePickTool(self); +		LLUploadDialog::modalUploadDialog("Uploading...\n\nReport"); +		// *TODO don't upload image if checkbox isn't checked +		std::string url = gAgent.getRegion()->getCapability("SendUserReport"); +		std::string sshot_url = gAgent.getRegion()->getCapability("SendUserReportWithScreenshot"); +		if(!url.empty() || !sshot_url.empty()) +		{ +			self->sendReportViaCaps(url, sshot_url, self->gatherReport()); +			self->close(); +		} +		else +		{ +			if(self->childGetValue("screen_check")) +			{ +				self->childDisable("send_btn"); +				self->childDisable("cancel_btn"); +				// the callback from uploading the image calls sendReportViaLegacy() +				self->uploadImage(); +			} +			else +			{ +				self->sendReportViaLegacy(self->gatherReport()); +				LLUploadDialog::modalUploadFinished(); +				self->close(); +			} +		}  	} -	self->sendReport();  } @@ -532,10 +564,9 @@ void LLFloaterReporter::setPickedObjectProperties(const char *object_name, const  	childSetText("owner_name", owner_name);  } -void LLFloaterReporter::sendReport() + +bool LLFloaterReporter::validateReport()  { -	LLViewerRegion *regionp = gAgent.getRegion(); -	if (!regionp) return;  	// Ensure user selected a category from the list  	LLSD category_sd = childGetValue("category_combo");  	U8 category = (U8)category_sd.asInteger(); @@ -549,7 +580,7 @@ void LLFloaterReporter::sendReport()  		{  			gViewerWindow->alertXml("HelpReportBugSelectCategory");  		} -		return; +		return false;  	}  	if ( mReportType != BUG_REPORT ) @@ -557,13 +588,13 @@ void LLFloaterReporter::sendReport()  	  if ( childGetText("abuser_name_edit").empty() )  	  {  		  gViewerWindow->alertXml("HelpReportAbuseAbuserNameEmpty"); -		  return; +		  return false;  	  };  	  if ( childGetText("abuse_location_edit").empty() )  	  {  		  gViewerWindow->alertXml("HelpReportAbuseAbuserLocationEmpty"); -		  return; +		  return false;  	  };  	}; @@ -577,7 +608,7 @@ void LLFloaterReporter::sendReport()  		{  			gViewerWindow->alertXml("HelpReportBugSummaryEmpty");  		} -		return; +		return false;  	};  	if ( childGetText("details_edit") == mDefaultSummary ) @@ -590,53 +621,19 @@ void LLFloaterReporter::sendReport()  		{  			gViewerWindow->alertXml("HelpReportBugDetailsEmpty");  		} -		return; +		return false;  	}; +	return true; +} + +LLSD LLFloaterReporter::gatherReport() +{	 +	LLViewerRegion *regionp = gAgent.getRegion(); +	if (!regionp) return LLSD(); // *TODO handle this failure case more gracefully  	// reset flag in case the next report also contains this text  	mCopyrightWarningSeen = FALSE; -	U32 check_flags = 0; -	if (childGetValue("screen_check")) -	{ -		check_flags |= INCLUDE_SCREENSHOT; -	} - -	LLMessageSystem *msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_UserReport); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -	msg->nextBlockFast(_PREHASH_ReportData); -	msg->addU8Fast(_PREHASH_ReportType, 	(U8) mReportType); -	msg->addU8(_PREHASH_Category, category); -	msg->addVector3Fast(_PREHASH_Position, 	mPosition); -	msg->addU8Fast(_PREHASH_CheckFlags, 	(U8) check_flags); - -	// only send a screenshot ID if we're asked too and the email is  -	// going to LL - Estate Owners cannot see the screenshot asset -	LLSD screenshot_id = LLUUID::null; -	if (childGetValue("screen_check")) -	{ -		if ( mReportType != BUG_REPORT ) -		{ -			if ( gEmailToEstateOwner == FALSE ) -			{ -				screenshot_id = childGetValue("screenshot"); -			} -		} -		else -		{ -			screenshot_id = childGetValue("screenshot"); -		}; -	}; -	msg->addUUIDFast(_PREHASH_ScreenshotID, screenshot_id); -	msg->addUUIDFast(_PREHASH_ObjectID, 	mObjectID); - -	msg->addUUID("AbuserID", mAbuserID ); -	msg->addString("AbuseRegionName", ""); -	msg->addUUID("AbuseRegionID", LLUUID::null); -  	std::ostringstream summary;  	if (!gInProductionGrid)  	{ @@ -684,7 +681,6 @@ void LLFloaterReporter::sendReport()  			<< " {" << childGetText("abuser_name_edit") << "} "					// name of abuse entered in report (chosen using LLAvatarPicker)  			<< " \"" << childGetValue("summary_edit").asString() << "\"";		// summary as entered  	}; -	msg->addStringFast(_PREHASH_Summary, summary.str().c_str());  	std::ostringstream details;  	if (mReportType != BUG_REPORT) @@ -709,7 +705,6 @@ void LLFloaterReporter::sendReport()  	};  	details << childGetValue("details_edit").asString(); -	msg->addStringFast(_PREHASH_Details, details.str() );  	char version_string[MAX_STRING];		/* Flawfinder: ignore */  	snprintf(version_string,						/* Flawfinder: ignore */ @@ -722,120 +717,204 @@ void LLFloaterReporter::sendReport()  			gSysCPU.getFamily().c_str(),  			gGLManager.mGLRenderer.c_str(),  			gGLManager.mDriverVersionVendorString.c_str()); -	msg->addString("VersionString", version_string); -	msg->sendReliable(regionp->getHost()); +	// only send a screenshot ID if we're asked to and the email is  +	// going to LL - Estate Owners cannot see the screenshot asset +	LLUUID screenshot_id = LLUUID::null; +	if (childGetValue("screen_check")) +	{ +		if ( mReportType != BUG_REPORT ) +		{ +			if ( gEmailToEstateOwner == FALSE ) +			{ +				screenshot_id = childGetValue("screenshot"); +			} +		} +		else +		{ +			screenshot_id = childGetValue("screenshot"); +		}; +	}; -	close(); +	LLSD report = LLSD::emptyMap(); +	report["report-type"] = (U8) mReportType; +	report["category"] = childGetValue("category_combo"); +	report["position"] = mPosition.getValue(); +	report["check-flags"] = (U8)0; // this is not used +	report["screenshot-id"] = screenshot_id; +	report["object-id"] = mObjectID; +	report["abuser-id"] = mAbuserID; +	report["abuse-region-name"] = ""; +	report["abuse-region-id"] = LLUUID::null; +	report["summary"] = summary.str(); +	report["version-string"] = version_string; +	report["details"] = details.str(); +	return report;  } +void LLFloaterReporter::sendReportViaLegacy(const LLSD & report) +{ +	LLViewerRegion *regionp = gAgent.getRegion(); +	if (!regionp) return; +	LLMessageSystem *msg = gMessageSystem; +	msg->newMessageFast(_PREHASH_UserReport); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	 +	msg->nextBlockFast(_PREHASH_ReportData); +	msg->addU8Fast(_PREHASH_ReportType, report["report-type"].asInteger()); +	msg->addU8(_PREHASH_Category, report["category"].asInteger()); +	msg->addVector3Fast(_PREHASH_Position, 	LLVector3(report["position"])); +	msg->addU8Fast(_PREHASH_CheckFlags, report["check-flags"].asInteger()); +	msg->addUUIDFast(_PREHASH_ScreenshotID, report["screenshot-id"].asUUID()); +	msg->addUUIDFast(_PREHASH_ObjectID, report["object-id"].asUUID()); +	msg->addUUID("AbuserID", report["abuser-id"].asUUID()); +	msg->addString("AbuseRegionName", report["abuse-region-name"].asString()); +	msg->addUUID("AbuseRegionID", report["abuse-region-id"].asUUID()); + +	msg->addStringFast(_PREHASH_Summary, report["summary"].asString().c_str()); +	msg->addString("VersionString", report["version-string"]); +	msg->addStringFast(_PREHASH_Details, report["details"] ); +	 +	msg->sendReliable(regionp->getHost()); +} -void LLFloaterReporter::uploadScreenshot() +class LLUserReportScreenshotResponder : public LLAssetUploadResponder +{ +public: +	LLUserReportScreenshotResponder(const LLSD & post_data,  +									const LLUUID & vfile_id,  +									LLAssetType::EType asset_type): +	  LLAssetUploadResponder(post_data, vfile_id, asset_type) +	{ +	} +	void uploadFailed(const LLSD& content) +	{ +		// *TODO pop up a dialog so the user knows their report screenshot didn't make it +		LLUploadDialog::modalUploadFinished(); +	} +	void uploadComplete(const LLSD& content) +	{ +		// we don't care about what the server returns from this post, just clean up the UI +		LLUploadDialog::modalUploadFinished(); +	} +}; + +class LLUserReportResponder : public LLHTTPClient::Responder +{ +public: +	LLUserReportResponder(): LLHTTPClient::Responder()  {} + +	void error(U32 status, const std::string& reason) +	{ +		// *TODO do some user messaging here +		LLUploadDialog::modalUploadFinished(); +	} +	void result(const LLSD& content) +	{ +		// we don't care about what the server returns +		LLUploadDialog::modalUploadFinished(); +	} +}; + +void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report) +{ +	if(childGetValue("screen_check").asBoolean() && !sshot_url.empty()) +	{ +		// try to upload screenshot +		LLHTTPClient::post(sshot_url, report, new LLUserReportScreenshotResponder(report,  +															mResourceDatap->mAssetInfo.mUuid,  +															mResourceDatap->mAssetInfo.mType));			 +	} +	else +	{ +		// screenshot not wanted or we don't have screenshot cap +		LLHTTPClient::post(url, report, new LLUserReportResponder());			 +	} +} + +void LLFloaterReporter::takeScreenshot()  {  	const S32 IMAGE_WIDTH = 1024;  	const S32 IMAGE_HEIGHT = 768; -	LLString filename("report_screenshot.bmp"); -	if( !gViewerWindow->saveSnapshot( filename, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE ) ) +	LLPointer<LLImageRaw> raw = new LLImageRaw; +	if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, TRUE, FALSE))  	{ +		llwarns << "Unable to take screenshot" << llendl;  		return;  	} +	LLPointer<LLImageJ2C> upload_data = LLViewerImageList::convertToUploadFile(raw); -	// Generate the temporary filename -	std::string temp_filename = gDirUtilp->getTempFilename(); - -	// try to create the upload file -	if (!LLViewerImageList::createUploadFile(filename, -										 	temp_filename, -										 	IMG_CODEC_BMP )) +	// create a resource data +	mResourceDatap->mInventoryType = LLInventoryType::IT_NONE; +	mResourceDatap->mAssetInfo.mTransactionID.generate(); +	mResourceDatap->mAssetInfo.mUuid = mResourceDatap->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID()); +	if (BUG_REPORT == mReportType)  	{ -		llwarns << "Unable to upload report screenshot " << filename << ":\n\n" << LLImageBase::getLastError() << "\n" << llendl; -		if(LLFile::remove(temp_filename.c_str()) == -1) -		{ -			lldebugs << "unable to remove temp file" << llendl; -		} -		LLFilePicker::instance().reset(); +		mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE; +		mResourceDatap->mPreferredLocation = LLAssetType::EType(-1); +	} +	else if (COMPLAINT_REPORT == mReportType) +	{ +		mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE; +		mResourceDatap->mPreferredLocation = LLAssetType::EType(-2);  	}  	else  	{ -		// create a resource data -		LLResourceData* data = NULL; -		data = new LLResourceData; -		data->mInventoryType = LLInventoryType::IT_NONE; -		data->mAssetInfo.mTransactionID.generate(); -		data->mAssetInfo.mUuid = data->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID()); -		if (BUG_REPORT == mReportType) -		{ -			//data->mAssetInfo.mType = LLAssetType::AT_BUG_REPORT_SCREENSHOT; -			data->mAssetInfo.mType = LLAssetType::AT_TEXTURE; -			data->mPreferredLocation = LLAssetType::EType(-1); -		} -		else if (COMPLAINT_REPORT == mReportType) -		{ -			//data->mAssetInfo.mType = LLAssetType::AT_COMPLAINT_REPORT_SCREENSHOT; -			data->mAssetInfo.mType = LLAssetType::AT_TEXTURE; -			data->mPreferredLocation = LLAssetType::EType(-2); -		} -		else -		{ -			llwarns << "Unknown LLFloaterReporter type" << llendl; -		} -		data->mAssetInfo.mCreatorID = gAgentID; -		data->mAssetInfo.setName("screenshot_name"); -		data->mAssetInfo.setDescription("screenshot_descr"); - -		llinfos << "*** Uploading: " << llendl; -		llinfos << "Type: " << LLAssetType::lookup(data->mAssetInfo.mType) << llendl; -		llinfos << "File: " << filename << llendl; -		llinfos << "Dest: " << temp_filename << llendl; -		llinfos << "Name: " << data->mAssetInfo.getName() << llendl; -		llinfos << "Desc: " << data->mAssetInfo.getDescription() << llendl; - -		gAssetStorage->storeAssetData(temp_filename.c_str(), -										data->mAssetInfo.mTransactionID, -										data->mAssetInfo.mType, -										LLFloaterReporter::uploadDoneCallback, -										(void*)data, TRUE); +		llwarns << "Unknown LLFloaterReporter type" << llendl; +	} +	mResourceDatap->mAssetInfo.mCreatorID = gAgentID; +	mResourceDatap->mAssetInfo.setName("screenshot_name"); +	mResourceDatap->mAssetInfo.setDescription("screenshot_descr"); + +	// store in VFS +	LLVFile::writeFile(upload_data->getData(),  +						upload_data->getDataSize(),  +						gVFS,  +						mResourceDatap->mAssetInfo.mUuid,  +						mResourceDatap->mAssetInfo.mType); + +	// store in the image list so it doesn't try to fetch from the server +	LLViewerImage* image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid, TRUE); +	image_in_list->createGLTexture(0, raw); +	gImageList.addImage(image_in_list);  + +	// the texture picker then uses that texture +	LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(this, "screenshot"); +	if (texture) +	{ +		texture->setImageAssetID(mResourceDatap->mAssetInfo.mUuid); +		texture->setDefaultImageAssetID(mResourceDatap->mAssetInfo.mUuid); +		texture->setCaption("Screenshot");  	} + +} + +void LLFloaterReporter::uploadImage() +{ +	llinfos << "*** Uploading: " << llendl; +	llinfos << "Type: " << LLAssetType::lookup(mResourceDatap->mAssetInfo.mType) << llendl; +	llinfos << "UUID: " << mResourceDatap->mAssetInfo.mUuid << llendl; +	llinfos << "Name: " << mResourceDatap->mAssetInfo.getName() << llendl; +	llinfos << "Desc: " << mResourceDatap->mAssetInfo.getDescription() << llendl; + +	gAssetStorage->storeAssetData(mResourceDatap->mAssetInfo.mTransactionID, +									mResourceDatap->mAssetInfo.mType, +									LLFloaterReporter::uploadDoneCallback, +									(void*)mResourceDatap, TRUE);  }  // static  void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, S32 result) // StoreAssetData callback (fixed)  { -	LLResourceData* data = (LLResourceData*)user_data; +	LLUploadDialog::modalUploadFinished(); -	if(result >= 0) -	{ -		EReportType report_type = UNKNOWN_REPORT; -		if (data->mPreferredLocation == -1) -		{ -			report_type = BUG_REPORT; -		} -		else if (data->mPreferredLocation == -2) -		{ -			report_type = COMPLAINT_REPORT; -		} -		else  -		{ -			llwarns << "Unknown report type : " << data->mPreferredLocation << llendl; -		} +	LLResourceData* data = (LLResourceData*)user_data; -		LLFloaterReporter *self = getReporter(report_type); -		if (self) -		{ -			LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(self, "screenshot"); -			if (texture) -			{ -				texture->setImageAssetID(uuid); -				texture->setDefaultImageAssetID(uuid); -				texture->setCaption("Screenshot"); -			} -			self->mScreenID = uuid; -			llinfos << "Got screen shot " << uuid << llendl; -		} -	} -	else // 	if(result >= 0) +	if(result < 0)  	{  		LLStringBase<char>::format_map_t args;  		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result)); @@ -844,8 +923,31 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,  		std::string err_msg("There was a problem uploading a report screenshot");  		err_msg += " due to the following reason: " + args["[REASON]"];  		llwarns << err_msg << llendl; +		return; +	} + +	EReportType report_type = UNKNOWN_REPORT; +	if (data->mPreferredLocation == -1) +	{ +		report_type = BUG_REPORT;  	} -	delete data; +	else if (data->mPreferredLocation == -2) +	{ +		report_type = COMPLAINT_REPORT; +	} +	else  +	{ +		llwarns << "Unknown report type : " << data->mPreferredLocation << llendl; +	} + +	LLFloaterReporter *self = getReporter(report_type); +	if (self) +	{ +		self->mScreenID = uuid; +		llinfos << "Got screen shot " << uuid << llendl; +		self->sendReportViaLegacy(self->gatherReport()); +	} +	self->close();  } diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index 795ef45e53..e8483b98ef 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -21,6 +21,7 @@ class LLViewerObject;  class LLAgent;  class LLToolObjPicker;  class LLMeanCollisionData; +struct LLResourceData;  // these flags are used to label info requests to the server  const U32 BUG_REPORT_REQUEST 		= 0x01 << 0; @@ -51,7 +52,6 @@ enum EReportType  	CS_REQUEST_REPORT = 4  }; -  class LLFloaterReporter  :	public LLFloater  { @@ -87,11 +87,16 @@ public:  	static void processRegionInfo(LLMessageSystem* msg);  	void setPickedObjectProperties(const char *object_name, const char *owner_name); -	void uploadScreenshot();  private: +	void takeScreenshot(); +	void sendReportViaCaps(std::string url); +	void uploadImage(); +	bool validateReport();  	void setReporterID(); -	void sendReport(); +	LLSD gatherReport(); +	void sendReportViaLegacy(const LLSD & report); +	void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);  	void setPosBox(const LLVector3d &pos);  	void enableControls(BOOL own_avatar);  	void getObjectInfo(const LLUUID& object_id); @@ -108,6 +113,7 @@ private:  	BOOL			mCopyrightWarningSeen;  	std::list<LLMeanCollisionData*> mMCDList;  	LLString		mDefaultSummary; +	LLResourceData* mResourceDatap;  };  #endif diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 34f394610f..c178d0d416 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -163,18 +163,8 @@ BOOL LLFloaterTOS::postBuild()  		gResponsePtr = LLIamHere::build( this );  		LLHTTPClient::get( childGetValue( "real_url" ).asString(), gResponsePtr );  	}; -	#else -	LLTextEditor *Editor = LLUICtrlFactory::getTextEditorByName(this, "tos_text"); -	if (Editor) -	{ -		Editor->setHandleEditKeysDirectly( TRUE ); -		Editor->setEnabled( FALSE ); -		Editor->setReadOnlyFgColor(LLColor4::white); -		Editor->setWordWrap(TRUE); -		Editor->setFocus(TRUE); -	} -	childSetValue("tos_text", LLSD(mMessage));	  	#endif +  	return TRUE;  } diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 938976241b..862dbcf377 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -22,6 +22,7 @@  // newview  #include "llagent.h"		// todo: remove +#include "llassetuploadresponders.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llcombobox.h" @@ -38,6 +39,7 @@  #include "llviewerinventory.h"  #include "llviewerobject.h"  #include "llviewerobjectlist.h" +#include "llviewerregion.h"  #include "llviewerstats.h"  #include "llviewerwindow.h"		// busycount  #include "viewer.h"			// gVFS @@ -1101,13 +1103,31 @@ void LLPreviewGesture::saveIfNeeded()  		LLInventoryItem* item = getItem();  		if (item)  		{ -			LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc"); -			LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); - -			const BOOL temp_file = FALSE; - -			gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, temp_file); - +			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 diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 6b8cc626ee..154ce5b07c 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -13,6 +13,7 @@  #include "llinventory.h"  #include "llagent.h" +#include "llassetuploadresponders.h"  #include "llviewerwindow.h"  #include "llbutton.h"  #include "llinventorymodel.h" @@ -219,6 +220,22 @@ const LLInventoryItem* LLPreviewNotecard::getDragItem()  	return NULL;  } +bool LLPreviewNotecard::hasEmbeddedInventory() +{ +	LLViewerTextEditor* editor = NULL; +	editor = LLViewerUICtrlFactory::getViewerTextEditorByName( +		this, +		"Notecard Editor"); +	if (!editor) return false; +	return editor->hasEmbeddedInventory(); +} + +void LLPreviewNotecard::refreshFromInventory() +{ +	lldebugs << "LLPreviewNotecard::refreshFromInventory()" << llendl; +	loadAsset(); +} +  void LLPreviewNotecard::loadAsset()  {  	// request the asset. @@ -348,7 +365,7 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,  			LLInventoryItem* item = preview->getItem();  			BOOL modifiable = item && gAgent.allowOperation(PERM_MODIFY,  								item->getPermissions(), GP_OBJECT_MANIPULATE); -			previewEditor->setEnabled(modifiable); +			preview->setEnabled(modifiable);  			delete[] buffer;  			preview->mAssetStatus = PREVIEW_ASSET_LOADED;  		} @@ -453,14 +470,43 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)  		LLInventoryItem* item = getItem();  		// save it out to database  		if (item) -		{ -			 -			LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID, -															  tid, copyitem); -			gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD, -											&onSaveComplete, -											(void*)info, -											FALSE); +		{			 +			std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory"); +			std::string task_url = gAgent.getRegion()->getCapability("UpdateNotecardTaskInventory"); +			if (mObjectUUID.isNull() && !agent_url.empty()) +			{ +				// Saving into agent inventory +				mAssetStatus = PREVIEW_ASSET_LOADING; +				setEnabled(FALSE); +				LLSD body; +				body["item_id"] = mItemUUID; +				llinfos << "Saving notecard " << mItemUUID +					<< " into agent inventory via " << agent_url << llendl; +				LLHTTPClient::post(agent_url, body, +					new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD)); +			} +			else if (!mObjectUUID.isNull() && !task_url.empty()) +			{ +				// Saving into task inventory +				mAssetStatus = PREVIEW_ASSET_LOADING; +				setEnabled(FALSE); +				LLSD body; +				body["task_id"] = mObjectUUID; +				body["item_id"] = mItemUUID; +				llinfos << "Saving notecard " << mItemUUID << " into task " +					<< mObjectUUID << " via " << task_url << llendl; +				LLHTTPClient::post(task_url, body, +					new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD)); +			} +			else if (gAssetStorage) +			{ +				LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID, +																tid, copyitem); +				gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD, +												&onSaveComplete, +												(void*)info, +												FALSE); +			}  		}  	}  	return true; diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 3bb3da5f54..730c56833a 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -50,6 +50,14 @@ public:  	const LLInventoryItem* getDragItem(); +	// return true if there is any embedded inventory. +	bool hasEmbeddedInventory(); + +	// After saving a notecard, the tcp based upload system will +	// change the asset, therefore, we need to re-fetch it from the +	// asset system. :( +	void refreshFromInventory(); +  protected:  	virtual void loadAsset(); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 479f1b1812..a7d29a6591 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -11,6 +11,7 @@  #include "llpreviewscript.h"  #include "llassetstorage.h" +#include "llassetuploadresponders.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llcombobox.h" @@ -832,6 +833,33 @@ LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect,  	}  } +// virtual +void LLPreviewLSL::callbackLSLCompileSucceeded() +{ +	llinfos << "LSL Bytecode saved" << llendl; +	mScriptEd->mErrorList->addSimpleItem("Compile successful!"); +	mScriptEd->mErrorList->addSimpleItem("Save complete."); +	closeIfNeeded(); +} + +// virtual +void LLPreviewLSL::callbackLSLCompileFailed(const LLSD& compile_errors) +{ +	llinfos << "Compile failed!" << llendl; + +	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); +	LLScrollListItem* item = NULL; +	for(LLSD::array_const_iterator line = compile_errors.beginArray(); +		line < compile_errors.endArray(); +		line++) +	{ +		item = new LLScrollListItem(); +		item->addColumn(line->asString(), err_font); +		mScriptEd->mErrorList->addItem(item); +	} +	mScriptEd->selectFirstError(); +	closeIfNeeded(); +}  void LLPreviewLSL::loadAsset()  { @@ -893,6 +921,17 @@ BOOL LLPreviewLSL::canClose()  	return mScriptEd->canClose();  } +void LLPreviewLSL::closeIfNeeded() +{ +	// Find our window and close it if requested. +	getWindow()->decBusyCount(); +	mPendingUploads--; +	if (mPendingUploads <= 0 && mCloseAfterSave) +	{ +		close(); +	} +} +  //override the llpreview open which attempts to load asset, load after xml ui made  void LLPreviewLSL::open()		/*Flawfinder: ignore*/  { @@ -914,152 +953,152 @@ void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save)  	self->saveIfNeeded();  } -  // Save needs to compile the text in the buffer. If the compile  // succeeds, then save both assets out to the database. If the compile  // fails, go ahead and save the text anyway so that the user doesn't  // get too fucked.  void LLPreviewLSL::saveIfNeeded()  { -	// llinfos << "LLPreviewLSL::save()" << llendl; -	if(!mScriptEd->mEditor->isPristine()) +	// llinfos << "LLPreviewLSL::saveIfNeeded()" << llendl; +	if(mScriptEd->mEditor->isPristine())  	{ -		mPendingUploads = 0; -		mScriptEd->mErrorList->deleteAllItems(); -		mScriptEd->mEditor->makePristine(); - -		// We need to update the asset information -		LLTransactionID tid; -		LLAssetID uuid; -		tid.generate(); -		uuid = tid.makeAssetID(gAgent.getSecureSessionID()); -		char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/ -		uuid.toString(uuid_string); -		char filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -		snprintf(filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -		FILE* fp = LLFile::fopen(filename, "wb");		/*Flawfinder: ignore*/ -		if(!fp) -		{ -			llwarns << "Unable to write to " << filename << llendl; -			LLScrollListItem* item = new LLScrollListItem(); -			item->addColumn("Error writing to local file. Is your hard drive full?", LLFontGL::sSansSerifSmall); -			mScriptEd->mErrorList->addItem(item); -			return; -		} +		return; +	} -		LLString utf8text = mScriptEd->mEditor->getText(); -		//fprintf(fp, "%s|%s\n", LLAssetType::lookup(LLAssetType::AT_LSL_TEXT), -		//uuid_string); -		//fprintf(fp,"{\n%s}\n", text.c_str()); -		fputs(utf8text.c_str(), fp); -		fclose(fp); -		fp = NULL; +	mPendingUploads = 0; +	mScriptEd->mErrorList->deleteAllItems(); +	mScriptEd->mEditor->makePristine(); -		// also write it out to the vfs for upload -		LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_TEXT, LLVFile::APPEND); -		S32 size = utf8text.length() + 1; +	// save off asset into file +	LLTransactionID tid; +	tid.generate(); +	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); +	std::string filename = llformat("%s.lsl", filepath.c_str()); -		file.setMaxSize(size); -		file.write((U8*)utf8text.c_str(), size); +	FILE* fp = LLFile::fopen(filename.c_str(), "wb"); +	if(!fp) +	{ +		llwarns << "Unable to write to " << filename << llendl; +		LLScrollListItem* item = new LLScrollListItem(); +		item->addColumn("Error writing to local file. Is your hard drive full?", LLFontGL::sSansSerifSmall); +		mScriptEd->mErrorList->addItem(item); +		return; +	} -		LLInventoryItem *inv_item = getItem(); +	LLString utf8text = mScriptEd->mEditor->getText(); +	fputs(utf8text.c_str(), fp); +	fclose(fp); +	fp = NULL; -		// save it out to database -		if(gAssetStorage && inv_item) +	LLInventoryItem *inv_item = getItem(); +	// save it out to asset server +	std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgentInventory"); +	if(inv_item) +	{ +		getWindow()->incBusyCount(); +		mPendingUploads++; +		if (!url.empty())  		{ -			getWindow()->incBusyCount(); -			mPendingUploads++; -			LLScriptSaveInfo* info = NULL; +			uploadAssetViaCaps(url, filename, mItemUUID); +		} +		else if (gAssetStorage) +		{ +			uploadAssetLegacy(filename, mItemUUID, tid); +		} +	} +} -			LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc"); +void LLPreviewLSL::uploadAssetViaCaps(const std::string& url, +									  const std::string& filename, +									  const LLUUID& item_id) +{ +	llinfos << "Update Agent Inventory via capability" << llendl; +	LLSD body; +	body["item_id"] = item_id; +	LLHTTPClient::post(url, body, new LLUpdateAgentInventoryResponder(body, filename)); +} -			info = new LLScriptSaveInfo(mItemUUID, -										descEditor->getText(), -										tid); -			gAssetStorage->storeAssetData(tid, LLAssetType::AT_LSL_TEXT, &LLPreviewLSL::onSaveComplete, info); -		} +void LLPreviewLSL::uploadAssetLegacy(const std::string& filename, +									  const LLUUID& item_id, +									  const LLTransactionID& tid) +{ +	LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc"); +	LLScriptSaveInfo* info = new LLScriptSaveInfo(item_id, +								descEditor->getText(), +								tid); +	gAssetStorage->storeAssetData(filename.c_str(),	tid, +								  LLAssetType::AT_LSL_TEXT, +								  &LLPreviewLSL::onSaveComplete, +								  info); -		char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -		snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -		char err_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -		snprintf(err_filename, LL_MAX_PATH, "%s.out", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -		LLScrollListItem* item = NULL; -		const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); -		if(!lscript_compile(filename, dst_filename, err_filename, gAgent.isGodlike())) -		{ -			llinfos << "Compile failed!" << llendl; -			//char command[256]; -			//sprintf(command, "type %s\n", err_filename); -			//system(command); +	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); +	std::string dst_filename = llformat("%s.lso", filepath.c_str()); +	std::string err_filename = llformat("%s.out", filepath.c_str()); -			// load the error file into the error scrolllist -			if(NULL != (fp = LLFile::fopen(err_filename, "r")))		/*Flawfinder: ignore*/ +	LLScrollListItem* item = NULL; +	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); +	if(!lscript_compile(filename.c_str(), +						dst_filename.c_str(), +						err_filename.c_str(), +						gAgent.isGodlike())) +	{ +		llinfos << "Compile failed!" << llendl; +		//char command[256]; +		//sprintf(command, "type %s\n", err_filename); +		//system(command); + +		// load the error file into the error scrolllist +		FILE* fp = LLFile::fopen(err_filename.c_str(), "r"); +		if(fp) +		{ +			char buffer[MAX_STRING];		/*Flawfinder: ignore*/ +			LLString line; +			while(!feof(fp))   			{ -				char buffer[MAX_STRING];		/*Flawfinder: ignore*/ -				LLString line; -				while(!feof(fp))  +				fgets(buffer, MAX_STRING, fp); +				if(feof(fp))  				{ -					 -					fgets(buffer, MAX_STRING, fp); -					if(feof(fp)) -					{ -						break; -					} -					else if(!buffer) -					{ -						continue; -					} -					else -					{ -						line.assign(buffer); -						LLString::stripNonprintable(line); -						item = new LLScrollListItem(); -						item->addColumn(line, err_font); -						mScriptEd->mErrorList->addItem(item); -					} +					break;  				} -				fclose(fp); -				mScriptEd->selectFirstError(); -			} -		} -		else -		{ -			llinfos << "Compile worked!" << llendl; -			if(gAssetStorage) -			{ -				// move the compiled file into the vfs for transport -				FILE* fp = LLFile::fopen(dst_filename, "rb");			/*Flawfinder: ignore*/ -				LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_BYTECODE, LLVFile::APPEND); - -				fseek(fp, 0, SEEK_END); -				S32 size = ftell(fp); -				fseek(fp, 0, SEEK_SET); - -				file.setMaxSize(size); - -				const S32 buf_size = 65536; -				U8 copy_buf[buf_size]; -				while ((size = fread(copy_buf, 1, buf_size, fp))) +				else if(!buffer)  				{ -					file.write(copy_buf, size); +					continue; +				} +				else +				{ +					line.assign(buffer); +					LLString::stripNonprintable(line); +					item = new LLScrollListItem(); +					item->addColumn(line, err_font); +					mScriptEd->mErrorList->addItem(item);  				} -				fclose(fp); -				fp = NULL; -				getWindow()->incBusyCount(); -				mPendingUploads++; -				LLUUID* this_uuid = new LLUUID(mItemUUID); -				gAssetStorage->storeAssetData(tid, -											  LLAssetType::AT_LSL_BYTECODE, -											  &LLPreviewLSL::onSaveBytecodeComplete, -											  (void**)this_uuid);  			} +			fclose(fp); +			mScriptEd->selectFirstError();  		} - -		// get rid of any temp files left lying around -		LLFile::remove(filename); -		LLFile::remove(err_filename); -		LLFile::remove(dst_filename);  	} +	else +	{ +		llinfos << "Compile worked!" << llendl; +		if(gAssetStorage) +		{ +			getWindow()->incBusyCount(); +			mPendingUploads++; +			LLUUID* this_uuid = new LLUUID(mItemUUID); +			gAssetStorage->storeAssetData(dst_filename.c_str(), +										  tid, +										  LLAssetType::AT_LSL_BYTECODE, +										  &LLPreviewLSL::onSaveBytecodeComplete, +										  (void**)this_uuid); +		} +	} + +	// get rid of any temp files left lying around +	LLFile::remove(filename.c_str()); +	LLFile::remove(err_filename.c_str()); +	LLFile::remove(dst_filename.c_str());  } @@ -1333,6 +1372,35 @@ void LLLiveLSLEditor::loadAsset()  	loadAsset(FALSE);  } +// virtual +void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id, +												  const LLUUID& item_id, +												  bool is_script_running) +{ +	lldebugs << "LSL Bytecode saved" << llendl; +	mScriptEd->mErrorList->addSimpleItem("Compile successful!"); +	mScriptEd->mErrorList->addSimpleItem("Save complete."); +	closeIfNeeded(); +} + +// virtual +void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors) +{ +	lldebugs << "Compile failed!" << llendl; +	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); +	LLScrollListItem* item = NULL; +	for(LLSD::array_const_iterator line = compile_errors.beginArray(); +		line < compile_errors.endArray(); +		line++) +	{ +		item = new LLScrollListItem(); +		item->addColumn(line->asString(), err_font); +		mScriptEd->mErrorList->addItem(item); +	} +	mScriptEd->selectFirstError(); +	closeIfNeeded(); +} +  void LLLiveLSLEditor::loadAsset(BOOL is_new)  {  	//llinfos << "LLLiveLSLEditor::loadAsset()" << llendl; @@ -1676,18 +1744,16 @@ void LLLiveLSLEditor::saveIfNeeded()  	// set up the save on the local machine.  	mScriptEd->mEditor->makePristine();  	LLTransactionID tid; -	LLAssetID uuid;  	tid.generate(); -	uuid = tid.makeAssetID(gAgent.getSecureSessionID()); -	mItem->setAssetUUID(uuid); +	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); +	std::string filename = llformat("%s.lsl", filepath.c_str()); + +	mItem->setAssetUUID(asset_id);  	mItem->setTransactionID(tid);  	// write out the data, and store it in the asset database -	char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/ -	uuid.toString(uuid_string); -	char filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -	snprintf(filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -	FILE* fp = LLFile::fopen(filename, "wb");		/*Flawfinder: ignore*/ +	FILE* fp = LLFile::fopen(filename.c_str(), "wb");  	if(!fp)  	{  		llwarns << "Unable to write to " << filename << llendl; @@ -1699,63 +1765,69 @@ void LLLiveLSLEditor::saveIfNeeded()  	LLString utf8text = mScriptEd->mEditor->getText();  	fputs(utf8text.c_str(), fp);  	fclose(fp); - -	LLCheckBoxCtrl* runningCheckbox = LLUICtrlFactory::getCheckBoxByName(this, "running"); +	fp = NULL; -	// save it out to database -	if(gAssetStorage) +	// save it out to asset server +	std::string url = gAgent.getRegion()->getCapability("UpdateScriptTaskInventory"); +	getWindow()->incBusyCount(); +	mPendingUploads++; +	BOOL is_running = LLUICtrlFactory::getCheckBoxByName(this, "running")->get(); +	if (!url.empty())  	{ -		// write it out to the vfs for upload -		LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_TEXT, LLVFile::APPEND); -		S32 size = utf8text.length() + 1; - -		file.setMaxSize(size); -		file.write((U8*)utf8text.c_str(), size); - -		getWindow()->incBusyCount(); -		mPendingUploads++; -		LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID, -														mItem, -														runningCheckbox->get()); -		gAssetStorage->storeAssetData(tid, LLAssetType::AT_LSL_TEXT, &onSaveTextComplete, (void*)data, FALSE); +		uploadAssetViaCaps(url, filename, mObjectID, +						   mItemID, is_running);  	} - -#if LL_WINDOWS -	// This major hack was inserted because sometimes compilation -	// would fail because it couldn't open this file... I decided -	// to make a loop until open was successful. This seems to be -	// a problem specific to ntfs. -	fp = NULL; -	const U32 MAX_TRIES = 20; -	U32 tries = MAX_TRIES; -	while((!fp) && --tries) +	else if (gAssetStorage)  	{ -		ms_sleep(17); -		fp = LLFile::fopen(filename, "r");		/*Flawfinder: ignore*/ -		if(!fp) -		{ -			llwarns << "Trying to open the source file " << filename -					<< " again" << llendl; -		} -		else -		{ -			fclose(fp); -		} +		uploadAssetLegacy(filename, object, tid, is_running);  	} -	fp = NULL; -#endif +} + +void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url, +										 const std::string& filename, +										 const LLUUID& task_id, +										 const LLUUID& item_id, +										 BOOL is_running) +{ +	llinfos << "Update Task Inventory via capability" << llendl; +	LLSD body; +	body["task_id"] = task_id; +	body["item_id"] = item_id; +	body["is_script_running"] = is_running; +	LLHTTPClient::post(url, body, +		new LLUpdateTaskInventoryResponder(body, filename)); +} + +void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, +										LLViewerObject* object, +										const LLTransactionID& tid, +										BOOL is_running) +{ +	LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID, +													mItem, +													is_running); +	gAssetStorage->storeAssetData(filename.c_str(), tid, +								  LLAssetType::AT_LSL_TEXT, +								  &onSaveTextComplete, +								  (void*)data, +								  FALSE); + +	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); +	std::string dst_filename = llformat("%s.lso", filepath.c_str()); +	std::string err_filename = llformat("%s.out", filepath.c_str()); -	char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -	snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -	char err_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -	snprintf(err_filename, LL_MAX_PATH, "%s.out", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/  	LLScrollListItem* item = NULL;  	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA); -	if(!lscript_compile(filename, dst_filename, err_filename, gAgent.isGodlike())) +	FILE *fp; +	if(!lscript_compile(filename.c_str(), +						dst_filename.c_str(), +						err_filename.c_str(), +						gAgent.isGodlike()))  	{  		// load the error file into the error scrolllist  		llinfos << "Compile failed!" << llendl; -		if(NULL != (fp = LLFile::fopen(err_filename, "r")))		/*Flawfinder: ignore*/ +		if(NULL != (fp = LLFile::fopen(err_filename.c_str(), "r")))  		{  			char buffer[MAX_STRING];		/*Flawfinder: ignore*/  			LLString line; @@ -1797,33 +1869,14 @@ void LLLiveLSLEditor::saveIfNeeded()  		{  			llinfos << "LLLiveLSLEditor::saveAsset "  					<< mItem->getAssetUUID() << llendl; - -			// move the compiled file into the vfs for transport -			FILE* fp = LLFile::fopen(dst_filename, "rb");		/*Flawfinder: ignore*/ -			LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_BYTECODE, LLVFile::APPEND); - -			fseek(fp, 0, SEEK_END); -			S32 size = ftell(fp); -			fseek(fp, 0, SEEK_SET); - -			file.setMaxSize(size); - -			const S32 buf_size = 65536; -			U8 copy_buf[buf_size]; -			while ((size = fread(copy_buf, 1, buf_size, fp))) -			{ -				file.write(copy_buf, size); -			} -			fclose(fp); -			fp = NULL; -  			getWindow()->incBusyCount();  			mPendingUploads++;  			LLLiveLSLSaveData* data = NULL;  			data = new LLLiveLSLSaveData(mObjectID,  										 mItem, -										 runningCheckbox->get()); -			gAssetStorage->storeAssetData(tid, +										 is_running); +			gAssetStorage->storeAssetData(dst_filename.c_str(), +										  tid,  										  LLAssetType::AT_LSL_BYTECODE,  										  &LLLiveLSLEditor::onSaveBytecodeComplete,  										  (void*)data); @@ -1832,11 +1885,12 @@ void LLLiveLSLEditor::saveIfNeeded()  	}  	// get rid of any temp files left lying around -	LLFile::remove(filename); -	LLFile::remove(err_filename); -	LLFile::remove(dst_filename); +	LLFile::remove(filename.c_str()); +	LLFile::remove(err_filename.c_str()); +	LLFile::remove(dst_filename.c_str());  	// If we successfully saved it, then we should be able to check/uncheck the running box! +	LLCheckBoxCtrl* runningCheckbox = LLUICtrlFactory::getCheckBoxByName(this, "running");  	runningCheckbox->setLabel(ENABLED_RUNNING_CHECKBOX_LABEL);  	runningCheckbox->setEnabled(TRUE);  } @@ -1912,13 +1966,10 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use  		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));  		gViewerWindow->alertXml("CompileQueueSaveBytecode", args);  	} -	char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/ -	data->mItem->getAssetUUID().toString(uuid_string); -	char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/ -	snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -	LLFile::remove(dst_filename); -	snprintf(dst_filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/ -	LLFile::remove(dst_filename); + +	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_uuid.asString()); +	std::string dst_filename = llformat("%s.lso", filepath.c_str()); +	LLFile::remove(dst_filename.c_str());  	delete data;  } @@ -1927,6 +1978,16 @@ BOOL LLLiveLSLEditor::canClose()  	return (mScriptEd->canClose());  } +void LLLiveLSLEditor::closeIfNeeded() +{ +	getWindow()->decBusyCount(); +	mPendingUploads--; +	if (mPendingUploads <= 0 && mCloseAfterSave) +	{ +		close(); +	} +} +  // static  void LLLiveLSLEditor::onLoad(void* userdata)  { @@ -1970,6 +2031,13 @@ void LLLiveLSLEditor::hide(const LLUUID& script_id, const LLUUID& object_id)  		delete instance;  	}  } +// static +LLLiveLSLEditor* LLLiveLSLEditor::find(const LLUUID& script_id, const LLUUID& object_id) +{ +	LLUUID xored_id = script_id ^ object_id; +	return sInstances.getIfThere(xored_id); +} +  // static  void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**) diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 9b2beb9ce9..5b15fda222 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -116,15 +116,24 @@ class LLPreviewLSL : public LLPreview  public:  	LLPreviewLSL(const std::string& name, const LLRect& rect, const std::string& title,  				 const LLUUID& item_uuid ); +	virtual void callbackLSLCompileSucceeded(); +	virtual void callbackLSLCompileFailed(const LLSD& compile_errors);  	/*virtual*/ void open();		/*Flawfinder: ignore*/  protected:  	virtual BOOL canClose(); +	void closeIfNeeded();  	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);  	virtual void loadAsset();  	void saveIfNeeded(); +	void uploadAssetViaCaps(const std::string& url, +							const std::string& filename,  +							const LLUUID& item_id); +	void uploadAssetLegacy(const std::string& filename, +							const LLUUID& item_id, +							const LLTransactionID& tid);  	static void onLoad(void* userdata);  	static void onSave(void* userdata, BOOL close_after_save); @@ -158,17 +167,33 @@ public:  	static LLLiveLSLEditor* show(const LLUUID& item_id, const LLUUID& object_id);  	static void hide(const LLUUID& item_id, const LLUUID& object_id); +	static LLLiveLSLEditor* find(const LLUUID& item_id, const LLUUID& object_id);  	static void processScriptRunningReply(LLMessageSystem* msg, void**); -	 + +	virtual void callbackLSLCompileSucceeded(const LLUUID& task_id, +											const LLUUID& item_id, +											bool is_script_running); +	virtual void callbackLSLCompileFailed(const LLSD& compile_errors); +  protected:  	virtual BOOL canClose(); +	void closeIfNeeded();  	virtual void draw();  	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);  	virtual void loadAsset();  	void loadAsset(BOOL is_new);  	void saveIfNeeded(); +	void uploadAssetViaCaps(const std::string& url, +							const std::string& filename,  +							const LLUUID& task_id, +							const LLUUID& item_id, +							BOOL is_running); +	void uploadAssetLegacy(const std::string& filename, +						   LLViewerObject* object, +						   const LLTransactionID& tid, +						   BOOL is_running);  	static void onLoad(void* userdata);  	static void onSave(void* userdata, BOOL close_after_save); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index e6c6576ae1..f8cc68d683 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -833,6 +833,7 @@ BOOL idle_startup()  		case USERSERVER_SHAKTI:  		case USERSERVER_DURGA:  		case USERSERVER_SOMA: +		case USERSERVER_VAAK:  		case USERSERVER_GANGA:  		case USERSERVER_UMA:  		{ @@ -2557,6 +2558,7 @@ void login_show()  	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_GANGA].mLabel,	USERSERVER_GANGA );  	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_UMA].mLabel,	USERSERVER_UMA );  	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SOMA].mLabel,	USERSERVER_SOMA ); +	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_VAAK].mLabel,	USERSERVER_VAAK );  }  // Callback for when login screen is closed.  Option 0 = connect, option 1 = quit. diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9ac566b02b..a638d99381 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -273,6 +273,7 @@ BOOL enable_save_as(void *);  // Edit menu  void handle_dump_group_info(void *); +void handle_dump_capabilities_info(void *);  void handle_dump_focus(void*);  void handle_region_dump_settings(void*); @@ -716,6 +717,8 @@ void init_client_menu(LLMenuGL* menu)  			&handle_region_dump_settings, NULL));  		sub->append(new LLMenuItemCallGL("Group Info to Debug Console",  			&handle_dump_group_info, NULL, NULL)); +		sub->append(new LLMenuItemCallGL("Capabilities Info to Debug Console", +			&handle_dump_capabilities_info, NULL, NULL));  		sub->createJumpKeys();  	} @@ -2451,6 +2454,14 @@ void handle_dump_group_info(void *)  	//llinfos << "insig   " << gAgent.mGroupInsigniaID << llendl;  } +void handle_dump_capabilities_info(void *) +{ +	LLViewerRegion* regionp = gAgent.getRegion(); +	if (regionp) +	{ +		regionp->logActiveCapabilities(); +	} +}  void handle_dump_focus(void *)  { @@ -5689,7 +5700,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty  	llinfos << "Desc: " << desc << llendl;  	lldebugs << "Folder: " << gInventory.findCategoryUUIDForType(destination_folder_type) << llendl;  	lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; -	std::string url = gAgent.getRegion()->getCapability("NewAgentInventory"); +	std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");  	if (!url.empty())  	{  		llinfos << "New Agent Inventory via capability" << llendl; @@ -5703,7 +5714,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty  		std::ostringstream llsdxml;  		LLSDSerialize::toXML(body, llsdxml);  		lldebugs << "posting body to capability: " << llsdxml.str() << llendl; -		LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(uuid, body)); +		LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));  	}  	else  	{ diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 189b314e55..f62949cadf 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -46,6 +46,10 @@ LLUserServerData gUserServerDomainName[USERSERVER_COUNT] =  	  "userserver.ganga.lindenlab.com",  	  "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",  	  "http://ganga-secondlife.webdev.lindenlab.com/helpers/" }, +	{ "Vaak", +	  "userserver.vaak.lindenlab.com", +	  "https://login.vaak.lindenlab.com/cgi-bin/login.cgi", +	  "http://vaak-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Uma",  	  "userserver.uma.lindenlab.com",  	  "https://login.uma.lindenlab.com/cgi-bin/login.cgi", diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index d461369d02..9eb2d9fcdd 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -23,6 +23,7 @@ enum EUserServerDomain  	USERSERVER_SHAKTI,  	USERSERVER_SOMA,  	USERSERVER_GANGA, +	USERSERVER_VAAK,  	USERSERVER_UMA,  	USERSERVER_LOCAL,  	USERSERVER_OTHER, // IP address set via -user or other command line option diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6a20aa4a95..a09ce3011f 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2323,41 +2323,45 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)  	LLUUID task_id;  	msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);  	LLViewerObject* object = gObjectList.findObject(task_id); -	if(object) +	if(!object)  	{ -		msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum); -		LLFilenameAndTask* ft = new LLFilenameAndTask; -		ft->mTaskID = task_id; -		msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, MAX_STRING, ft->mFilename); -		if(!ft->mFilename[0]) +		llwarns << "LLViewerObject::processTaskInv object " +			<< task_id << " does not exist." << llendl; +		return; +	} + +	msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum); +	LLFilenameAndTask* ft = new LLFilenameAndTask; +	ft->mTaskID = task_id; +	msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, MAX_STRING, ft->mFilename); +	if(!ft->mFilename[0]) +	{ +		lldebugs << "Task has no inventory" << llendl; +		// mock up some inventory to make a drop target. +		if(object->mInventory)  		{ -			lldebugs << "Task has no inventory" << llendl; -			// mock up some inventory to make a drop target. -			if(object->mInventory) -			{ -				object->mInventory->clear(); // will deref and delete it -			} -			else -			{ -				object->mInventory = new InventoryObjectList(); -			} -			LLPointer<LLInventoryObject> obj; -			obj = new LLInventoryObject(object->mID, LLUUID::null, -										LLAssetType::AT_CATEGORY, -										"Contents"); -			object->mInventory->push_front(obj); -			object->doInventoryCallback(); -			delete ft; -			return; +			object->mInventory->clear(); // will deref and delete it  		} -		gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename).c_str(),  -								  ft->mFilename, LL_PATH_CACHE, -								  object->mRegionp->getHost(), -								  TRUE, -								  &LLViewerObject::processTaskInvFile, -								  (void**)ft, -								  LLXferManager::HIGH_PRIORITY); +		else +		{ +			object->mInventory = new InventoryObjectList(); +		} +		LLPointer<LLInventoryObject> obj; +		obj = new LLInventoryObject(object->mID, LLUUID::null, +									LLAssetType::AT_CATEGORY, +									"Contents"); +		object->mInventory->push_front(obj); +		object->doInventoryCallback(); +		delete ft; +		return;  	} +	gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename).c_str(),  +								ft->mFilename, LL_PATH_CACHE, +								object->mRegionp->getHost(), +								TRUE, +								&LLViewerObject::processTaskInvFile, +								(void**)ft, +								LLXferManager::HIGH_PRIORITY);  }  void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code) @@ -2582,6 +2586,18 @@ LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& ass  	return rv;  } +void LLViewerObject::updateViewerInventoryAsset( +					const LLViewerInventoryItem* item, +					const LLUUID& new_asset) +{ +	LLPointer<LLViewerInventoryItem> task_item = +		new LLViewerInventoryItem(item); +	task_item->setAssetUUID(new_asset); + +	// do the internal logic +	doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false); +} +  void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)  {  	if (getVolume()) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index d8b5a14897..80d3240904 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -363,6 +363,11 @@ public:  	LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);  	S16 getInventorySerial() const { return mInventorySerialNum; } +	// These functions does viewer-side only object inventory modifications +	void updateViewerInventoryAsset( +		const LLViewerInventoryItem* item, +		const LLUUID& new_asset); +  	// This function will make sure that we refresh the inventory.  	void dirtyInventory();  	BOOL isInventoryDirty() { return mInventoryDirty; } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 5235410156..262c7d8ed7 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1260,8 +1260,19 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	LLSD capabilityNames = LLSD::emptyArray();  	capabilityNames.append("MapLayer");  	capabilityNames.append("MapLayerGod"); -	capabilityNames.append("NewAgentInventory"); +	capabilityNames.append("NewFileAgentInventory");  	capabilityNames.append("EventQueueGet"); +	capabilityNames.append("UpdateGestureAgentInventory"); +	capabilityNames.append("UpdateNotecardAgentInventory"); +	capabilityNames.append("UpdateScriptAgentInventory"); +	capabilityNames.append("UpdateGestureTaskInventory"); +	capabilityNames.append("UpdateNotecardTaskInventory"); +	capabilityNames.append("UpdateScriptTaskInventory"); +	capabilityNames.append("SendPostcard"); +	capabilityNames.append("ViewerStartAuction"); +	capabilityNames.append("ParcelGodReserveForNewbie"); +	capabilityNames.append("SendUserReport"); +	capabilityNames.append("SendUserReportWithScreenshot");  	capabilityNames.append("RequestTextureDownload");  	LLHTTPClient::post(url, capabilityNames, BaseCapabilitiesComplete::build(this));  } @@ -1304,3 +1315,16 @@ std::string LLViewerRegion::getCapability(const std::string& name) const  	return iter->second;  } +void LLViewerRegion::logActiveCapabilities() const +{ +	CapabilityMap::const_iterator iter; +	for (iter = mCapabilities.begin(); iter != mCapabilities.end(); iter++) +	{ +		if (!iter->second.empty()) +		{ +			// llinfos << "Active capability is " << iter->first << llendl; +			llinfos << iter->first << " URL is " << iter->second << llendl; +		} +	} +} + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b3392baf81..1dc1b3af20 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -169,6 +169,7 @@ public:  	void setSeedCapability(const std::string& url);  	void setCapability(const std::string& name, const std::string& url);  	std::string getCapability(const std::string& name) const; +	void logActiveCapabilities() const;  	const LLHost	&getHost() const			{ return mHost; }  	const U64 		&getHandle() const 			{ return mHandle; } diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 7d04f04528..259fa09309 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -53,6 +53,9 @@ public:  	LLEmbeddedItems(const LLViewerTextEditor* editor);  	~LLEmbeddedItems();  	void clear(); + +	// return true if there are no embedded items. +	bool empty();  	void	bindEmbeddedChars(const LLFontGL* font);  	void	unbindEmbeddedChars(const LLFontGL* font); @@ -115,6 +118,13 @@ void LLEmbeddedItems::clear()  		removeEmbeddedItem(*nextiter);  	}  	mEmbeddedUsedChars.clear(); +	mEmbeddedIndexedChars.clear(); +} + +bool LLEmbeddedItems::empty() +{ +	removeUnusedChars(); +	return mEmbeddedUsedChars.empty();  }  // Inserts a new unique entry @@ -1367,10 +1377,11 @@ S32 LLViewerTextEditor::insertEmbeddedItem( S32 pos, LLInventoryItem* item )  bool LLViewerTextEditor::importStream(std::istream& str)  { -	LLNotecard nc(MAX_NOTECARD_SIZE); +	LLNotecard nc(LLNotecard::MAX_SIZE);  	bool success = nc.importStream(str);  	if (success)  	{ +		mEmbeddedItemList->clear();  		const std::vector<LLPointer<LLInventoryItem> >& items = nc.getItems();  		mEmbeddedItemList->addItems(items);  		// Actually set the text @@ -1396,6 +1407,11 @@ void LLViewerTextEditor::copyInventory(LLInventoryItem* item)  								 item);  } +bool LLViewerTextEditor::hasEmbeddedInventory() +{ +	return (!(mEmbeddedItemList->empty())); +} +  ////////////////////////////////////////////////////////////////////////////  BOOL LLViewerTextEditor::importBuffer( const LLString& buffer ) @@ -1406,7 +1422,7 @@ BOOL LLViewerTextEditor::importBuffer( const LLString& buffer )  BOOL LLViewerTextEditor::exportBuffer( LLString& buffer )  { -	LLNotecard nc(MAX_NOTECARD_SIZE); +	LLNotecard nc(LLNotecard::MAX_SIZE);  	std::vector<LLPointer<LLInventoryItem> > embedded_items;  	mEmbeddedItemList->getEmbeddedItemList(embedded_items); diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index 99e971b33c..de57b68e7d 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -67,7 +67,14 @@ public:  		// If this starts a line, you need to prepend a newline.  	void copyInventory(LLInventoryItem* item); -	 + +	// returns true if there is embedded inventory. +	// *HACK: This is only useful because the notecard verifier may +	// change the asset if there is embedded inventory. This mechanism +	// should be changed to get a different asset id from the verifier +	// rather than checking if a re-load is necessary. Phoenix 2007-02-27 +	bool hasEmbeddedInventory(); +  protected:  	// Embedded object operations  	virtual llwchar	pasteEmbeddedItem(llwchar ext_char); diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 522e9c9a56..9e85e293d4 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -15,11 +15,13 @@  #include "llquantize.h"  #include "llagent.h" +#include "llassetuploadresponders.h"  #include "llviewerwindow.h"  #include "llfloatercustomize.h"  #include "llinventorymodel.h"  #include "llviewerimagelist.h"  #include "llviewerinventory.h" +#include "llviewerregion.h"  #include "llvoavatar.h"  #include "llwearable.h" @@ -886,11 +888,28 @@ void LLWearable::saveNewAsset()  	// save it out to database  	if( gAssetStorage )  	{ -		LLWearableSaveData* data = new LLWearableSaveData; -		data->mType = mType; -		gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(), -										&LLWearable::onSaveNewAssetComplete, -										(void*)data); +		 /* +		std::string url = gAgent.getRegion()->getCapability("NewAgentInventory"); +		if (!url.empty()) +		{ +			llinfos << "Update Agent Inventory via capability" << llendl; +			LLSD body; +			body["folder_id"] = gInventory.findCategoryUUIDForType(getAssetType()); +			body["asset_type"] = LLAssetType::lookup(getAssetType()); +			body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE); +			body["name"] = getName(); +			body["description"] = getDescription(); +			LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename)); +		} +		else +		{ +		} +		 */ +		 LLWearableSaveData* data = new LLWearableSaveData; +		 data->mType = mType; +		 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(), +                                     &LLWearable::onSaveNewAssetComplete, +                                     (void*)data);  	}  } diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 301ab310d9..2c04a34da8 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -324,12 +324,15 @@ class DarwinManifest(ViewerManifest):                  volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()                  # Copy everything in to the mounted .dmg -                for s,d in {self.get_dst_prefix():("Second Life " + self.args['grid']).strip()+ ".app", -                                        "lsl_guide.html":"Linden Scripting Language Guide.html", -                                        "releasenotes.txt":"Release Notes.txt", -                                        "installers/darwin/mac_image_hidden":".hidden", -                                        "installers/darwin/mac_image_background.tga":"background.tga", -                                        "installers/darwin/mac_image_DS_Store":".DS_Store"}.items(): +                # TODO change name of .app once mac_updater can handle it. +                for s,d in { +                        self.get_dst_prefix():"Second Life.app", +                        "lsl_guide.html":"Linden Scripting Language Guide.html", +                        "releasenotes.txt":"Release Notes.txt", +                        "installers/darwin/mac_image_hidden":".hidden", +                        "installers/darwin/mac_image_background.tga":"background.tga", +                        "installers/darwin/mac_image_DS_Store":".DS_Store"}.items(): +                                                  print "Copying to dmg", s, d                          self.copy_action(self.src_path_of(s), os.path.join(volpath, d)) | 
