summaryrefslogtreecommitdiff
path: root/indra/newview/llassetuploadresponders.cpp
diff options
context:
space:
mode:
authorJosh Bell <josh@lindenlab.com>2007-03-14 23:03:50 +0000
committerJosh Bell <josh@lindenlab.com>2007-03-14 23:03:50 +0000
commit00dbacb215da8d6b6739b4bcefebee552de89a9c (patch)
treee1256e1fa3b195a1128bb152a876729c7f9a163d /indra/newview/llassetuploadresponders.cpp
parentcf405184285c25723249d5a023b28d9498cf0c3f (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/llassetuploadresponders.cpp')
-rw-r--r--indra/newview/llassetuploadresponders.cpp518
1 files changed, 390 insertions, 128 deletions
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;
}
}