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