diff options
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)) |