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/llassetuploadresponders.cpp | |
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/llassetuploadresponders.cpp')
-rw-r--r-- | indra/newview/llassetuploadresponders.cpp | 518 |
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; } } |