00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llassetuploadresponders.h"
00035
00036 #include "llagent.h"
00037 #include "llfloaterbuycurrency.h"
00038 #include "lleconomy.h"
00039 #include "llfilepicker.h"
00040 #include "llfocusmgr.h"
00041 #include "llnotify.h"
00042 #include "llinventorymodel.h"
00043 #include "llinventoryview.h"
00044 #include "llpermissionsflags.h"
00045 #include "llpreviewnotecard.h"
00046 #include "llpreviewscript.h"
00047 #include "llpreviewgesture.h"
00048 #include "llgesturemgr.h"
00049 #include "llscrolllistctrl.h"
00050 #include "lluploaddialog.h"
00051 #include "llviewerobject.h"
00052 #include "llviewerobjectlist.h"
00053 #include "llviewermenufile.h"
00054 #include "llviewerwindow.h"
00055
00056 void dialog_refresh_all();
00057
00058 LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
00059 const LLUUID& vfile_id,
00060 LLAssetType::EType asset_type)
00061 : LLHTTPClient::Responder(),
00062 mPostData(post_data),
00063 mVFileID(vfile_id),
00064 mAssetType(asset_type)
00065 {
00066 if (!gVFS->getExists(vfile_id, asset_type))
00067 {
00068 llwarns << "LLAssetUploadResponder called with nonexistant vfile_id" << llendl;
00069 mVFileID.setNull();
00070 mAssetType = LLAssetType::AT_NONE;
00071 return;
00072 }
00073 }
00074
00075 LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
00076 const std::string& file_name)
00077 : LLHTTPClient::Responder(),
00078 mPostData(post_data),
00079 mFileName(file_name)
00080 {
00081 }
00082
00083 LLAssetUploadResponder::~LLAssetUploadResponder()
00084 {
00085 if (!mFileName.empty())
00086 {
00087
00088 LLFile::remove(mFileName.c_str());
00089 }
00090 }
00091
00092
00093 void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
00094 {
00095 llinfos << "LLAssetUploadResponder::error " << statusNum
00096 << " reason: " << reason << llendl;
00097 LLStringBase<char>::format_map_t args;
00098 switch(statusNum)
00099 {
00100 case 400:
00101 args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
00102 args["[REASON]"] = "Error in upload request. Please visit "
00103 "http://secondlife.com/support for help fixing this problem.";
00104 gViewerWindow->alertXml("CannotUploadReason", args);
00105 break;
00106 case 500:
00107 default:
00108 args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
00109 args["[REASON]"] = "The server is experiencing unexpected "
00110 "difficulties.";
00111 gViewerWindow->alertXml("CannotUploadReason", args);
00112 break;
00113 }
00114 LLUploadDialog::modalUploadFinished();
00115 }
00116
00117
00118 void LLAssetUploadResponder::result(const LLSD& content)
00119 {
00120 lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl;
00121
00122 std::string state = content["state"];
00123 if (state == "upload")
00124 {
00125 uploadUpload(content);
00126 }
00127 else if (state == "complete")
00128 {
00129
00130 if (mFileName.empty())
00131 {
00132
00133 gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType);
00134 }
00135 uploadComplete(content);
00136 }
00137 else
00138 {
00139 uploadFailure(content);
00140 }
00141 }
00142
00143 void LLAssetUploadResponder::uploadUpload(const LLSD& content)
00144 {
00145 std::string uploader = content["uploader"];
00146 if (mFileName.empty())
00147 {
00148 LLHTTPClient::postFile(uploader, mVFileID, mAssetType, this);
00149 }
00150 else
00151 {
00152 LLHTTPClient::postFile(uploader, mFileName, this);
00153 }
00154 }
00155
00156 void LLAssetUploadResponder::uploadFailure(const LLSD& content)
00157 {
00158 std::string reason = content["state"];
00159
00160 if (reason == "insufficient funds")
00161 {
00162 LLFloaterBuyCurrency::buyCurrency("Uploading costs", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
00163 }
00164 else
00165 {
00166 LLStringBase<char>::format_map_t args;
00167 args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
00168 args["[REASON]"] = content["message"].asString();
00169 gViewerWindow->alertXml("CannotUploadReason", args);
00170 }
00171 }
00172
00173 void LLAssetUploadResponder::uploadComplete(const LLSD& content)
00174 {
00175 }
00176
00177 LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data,
00178 const LLUUID& vfile_id,
00179 LLAssetType::EType asset_type)
00180 : LLAssetUploadResponder(post_data, vfile_id, asset_type)
00181 {
00182 }
00183
00184 LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name)
00185 : LLAssetUploadResponder(post_data, file_name)
00186 {
00187 }
00188
00189
00190 void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
00191 {
00192 lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl;
00193
00194 LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString().c_str());
00195 LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString().c_str());
00196
00197
00198
00199 if (asset_type == LLAssetType::AT_TEXTURE ||
00200 asset_type == LLAssetType::AT_SOUND ||
00201 asset_type == LLAssetType::AT_ANIMATION)
00202 {
00203 gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest);
00204 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
00205 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00206 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00207 gMessageSystem->nextBlockFast(_PREHASH_MoneyData);
00208 gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
00209 gAgent.sendReliableMessage();
00210
00211 LLString::format_map_t args;
00212 args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
00213 LLNotifyBox::showXml("UploadPayment", args);
00214 }
00215
00216
00217 llinfos << "Adding " << content["new_inventory_item"].asUUID() << " "
00218 << content["new_asset"].asUUID() << " to inventory." << llendl;
00219 if(mPostData["folder_id"].asUUID().notNull())
00220 {
00221 LLPermissions perm;
00222 U32 next_owner_perm;
00223 perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
00224 if (mPostData["inventory_type"].asString() == "snapshot")
00225 {
00226 next_owner_perm = PERM_ALL;
00227 }
00228 else
00229 {
00230 next_owner_perm = PERM_MOVE | PERM_TRANSFER;
00231 }
00232 perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm);
00233 S32 creation_date_now = time_corrected();
00234 LLPointer<LLViewerInventoryItem> item
00235 = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(),
00236 mPostData["folder_id"].asUUID(),
00237 perm,
00238 content["new_asset"].asUUID(),
00239 asset_type,
00240 inventory_type,
00241 mPostData["name"].asString(),
00242 mPostData["description"].asString(),
00243 LLSaleInfo::DEFAULT,
00244 LLInventoryItem::II_FLAGS_NONE,
00245 creation_date_now);
00246 gInventory.updateItem(item);
00247 gInventory.notifyObservers();
00248
00249
00250
00251 LLInventoryView* view = LLInventoryView::getActiveInventory();
00252 if(view)
00253 {
00254 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
00255
00256 view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
00257 if((LLAssetType::AT_TEXTURE == asset_type)
00258 || (LLAssetType::AT_SOUND == asset_type))
00259 {
00260 view->getPanel()->openSelected();
00261 }
00262
00263
00264 gFocusMgr.setKeyboardFocus(focus_ctrl);
00265 }
00266 }
00267 else
00268 {
00269 llwarns << "Can't find a folder to put it in" << llendl;
00270 }
00271
00272
00273 LLUploadDialog::modalUploadFinished();
00274
00275
00276
00277
00278 const char* next_file = LLFilePicker::instance().getNextFile();
00279 if(next_file)
00280 {
00281 const char* name = LLFilePicker::instance().getDirname();
00282
00283 LLString asset_name = name;
00284 LLString::replaceNonstandardASCII( asset_name, '?' );
00285 LLString::replaceChar(asset_name, '|', '?');
00286 LLString::stripNonprintable(asset_name);
00287 LLString::trim(asset_name);
00288
00289 char* asset_name_str = (char*)asset_name.c_str();
00290 char* end_p = strrchr(asset_name_str, '.');
00291 if( !end_p )
00292 {
00293 end_p = asset_name_str + strlen( asset_name_str );
00294 }
00295
00296 S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
00297
00298 asset_name = asset_name.substr( 0, len );
00299
00300 upload_new_resource(next_file, asset_name, asset_name,
00301 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
00302 }
00303 }
00304
00305
00306 LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
00307 const LLUUID& vfile_id,
00308 LLAssetType::EType asset_type)
00309 : LLAssetUploadResponder(post_data, vfile_id, asset_type)
00310 {
00311 }
00312
00313 LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
00314 const std::string& file_name)
00315 : LLAssetUploadResponder(post_data, file_name)
00316 {
00317 }
00318
00319
00320 void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
00321 {
00322 llinfos << "LLUpdateAgentInventoryResponder::result from capabilities" << llendl;
00323 LLUUID item_id = mPostData["item_id"];
00324
00325 LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(item_id);
00326 if(!item)
00327 {
00328 llwarns << "Inventory item for " << mVFileID
00329 << " is no longer in agent inventory." << llendl;
00330 return;
00331 }
00332
00333
00334 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00335 new_item->setAssetUUID(content["new_asset"].asUUID());
00336 gInventory.updateItem(new_item);
00337 gInventory.notifyObservers();
00338
00339 llinfos << "Inventory item " << item->getName() << " saved into "
00340 << content["new_asset"].asString() << llendl;
00341
00342 LLInventoryType::EType inventory_type = new_item->getInventoryType();
00343 switch(inventory_type)
00344 {
00345 case LLInventoryType::IT_NOTECARD:
00346 {
00347
00348
00349 LLPreviewNotecard* nc;
00350 nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
00351 if(nc)
00352 {
00353
00354
00355
00356
00357
00358
00359 if(nc->hasEmbeddedInventory())
00360 {
00361 gVFS->removeFile(
00362 content["new_asset"].asUUID(),
00363 LLAssetType::AT_NOTECARD);
00364 }
00365 nc->refreshFromInventory();
00366 }
00367 }
00368 break;
00369 case LLInventoryType::IT_LSL:
00370 {
00371
00372 LLPreviewLSL* preview = (LLPreviewLSL*)LLPreview::find(item_id);
00373 if (preview)
00374 {
00375
00376 if (content["compiled"])
00377 {
00378 preview->callbackLSLCompileSucceeded();
00379 }
00380 else
00381 {
00382 preview->callbackLSLCompileFailed(content["errors"]);
00383 }
00384 }
00385 }
00386 break;
00387
00388 case LLInventoryType::IT_GESTURE:
00389 {
00390
00391
00392 if (gGestureManager.isGestureActive(item_id))
00393 {
00394 LLUUID asset_id = new_item->getAssetUUID();
00395 gGestureManager.replaceGesture(item_id, asset_id);
00396 gInventory.notifyObservers();
00397 }
00398
00399
00400 LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id);
00401 if(previewp)
00402 {
00403 previewp->onUpdateSucceeded();
00404 }
00405
00406 }
00407 break;
00408 case LLInventoryType::IT_WEARABLE:
00409 default:
00410 break;
00411 }
00412 }
00413
00414
00415 LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
00416 const LLUUID& vfile_id,
00417 LLAssetType::EType asset_type)
00418 : LLAssetUploadResponder(post_data, vfile_id, asset_type)
00419 {
00420 }
00421
00422 LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
00423 const std::string& file_name)
00424 : LLAssetUploadResponder(post_data, file_name)
00425 {
00426 }
00427
00428
00429 void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
00430 {
00431 llinfos << "LLUpdateTaskInventoryResponder::result from capabilities" << llendl;
00432 LLUUID item_id = mPostData["item_id"];
00433 LLUUID task_id = mPostData["task_id"];
00434
00435 LLViewerObject* object = gObjectList.findObject(task_id);
00436 if (!object)
00437 {
00438 llwarns << "LLUpdateTaskInventoryResponder::uploadComplete task " << task_id
00439 << " no longer exist." << llendl;
00440 return;
00441 }
00442 LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(item_id);
00443 if (!item)
00444 {
00445 llwarns << "LLUpdateTaskInventoryResponder::uploadComplete item "
00446 << item_id << " is no longer in task " << task_id
00447 << "'s inventory." << llendl;
00448 return;
00449 }
00450 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00451
00452 object->updateViewerInventoryAsset(new_item, content["new_asset"]);
00453 dialog_refresh_all();
00454
00455 LLInventoryType::EType inventory_type = new_item->getInventoryType();
00456 switch(inventory_type)
00457 {
00458 case LLInventoryType::IT_NOTECARD:
00459 {
00460
00461
00462 LLPreviewNotecard* nc;
00463 nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
00464 if(nc)
00465 {
00466
00467
00468
00469
00470
00471
00472 if(nc->hasEmbeddedInventory())
00473 {
00474 gVFS->removeFile(
00475 content["new_asset"].asUUID(),
00476 LLAssetType::AT_NOTECARD);
00477 }
00478
00479 nc->refreshFromInventory();
00480 }
00481 }
00482 break;
00483 case LLInventoryType::IT_LSL:
00484 {
00485 LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id);
00486 if (preview)
00487 {
00488
00489 if (content["compiled"])
00490 {
00491 preview->callbackLSLCompileSucceeded(
00492 task_id,
00493 item_id,
00494 mPostData["is_script_running"]);
00495 }
00496 else
00497 {
00498 preview->callbackLSLCompileFailed(content["errors"]);
00499 }
00500 }
00501 }
00502 break;
00503 case LLInventoryType::IT_WEARABLE:
00504 default:
00505 break;
00506 }
00507 }