llviewermenufile.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llviewermenufile.h"
00035 
00036 // project includes
00037 #include "llagent.h"
00038 #include "llfilepicker.h"
00039 #include "llfloateranimpreview.h"
00040 #include "llfloaterbuycurrency.h"
00041 #include "llfloaterimagepreview.h"
00042 #include "llfloaternamedesc.h"
00043 #include "llfloatersnapshot.h"
00044 #include "llinventorymodel.h"   // gInventory
00045 #include "llresourcedata.h"
00046 #include "llstatusbar.h"
00047 #include "llviewercontrol.h"    // gSavedSettings
00048 #include "llviewerimagelist.h"
00049 #include "lluictrlfactory.h"
00050 #include "llviewermenu.h"       // gMenuHolder
00051 #include "llviewerregion.h"
00052 #include "llviewerstats.h"
00053 #include "llviewerwindow.h"
00054 #include "llappviewer.h"
00055 #include "lluploaddialog.h"
00056 
00057 
00058 // linden libraries
00059 #include "llassetuploadresponders.h"
00060 #include "lleconomy.h"
00061 #include "llhttpclient.h"
00062 #include "llmemberlistener.h"
00063 #include "llsdserialize.h"
00064 #include "llstring.h"
00065 #include "lltransactiontypes.h"
00066 #include "lluuid.h"
00067 #include "vorbisencode.h"
00068 
00069 // system libraries
00070 #include <boost/tokenizer.hpp>
00071 
00072 typedef LLMemberListener<LLView> view_listener_t;
00073 
00074 
00075 class LLFileEnableSaveAs : public view_listener_t
00076 {
00077         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00078         {
00079                 bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs();
00080                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
00081                 return true;
00082         }
00083 };
00084 
00085 class LLFileEnableUpload : public view_listener_t
00086 {
00087         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00088         {
00089                 bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
00090                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
00091                 return true;
00092         }
00093 };
00094 
00103 const char* upload_pick(void* data)
00104 {
00105         if( gAgent.cameraMouselook() )
00106         {
00107                 gAgent.changeCameraToDefault();
00108                 // This doesn't seem necessary. JC
00109                 // display();
00110         }
00111 
00112         LLFilePicker::ELoadFilter type;
00113         if(data)
00114         {
00115                 type = (LLFilePicker::ELoadFilter)((intptr_t)data);
00116         }
00117         else
00118         {
00119                 type = LLFilePicker::FFLOAD_ALL;
00120         }
00121 
00122         LLFilePicker& picker = LLFilePicker::instance();
00123         if (!picker.getOpenFile(type))
00124         {
00125                 llinfos << "Couldn't import objects from file" << llendl;
00126                 return NULL;
00127         }
00128 
00129         const char* filename = picker.getFirstFile();
00130         const char* ext = strrchr(filename, '.');
00131 
00132         //strincmp doesn't like NULL pointers
00133         if (ext == NULL)
00134         {
00135                 const char* short_name = strrchr(filename,
00136                                                                                  *gDirUtilp->getDirDelimiter().c_str());
00137                 
00138                 // No extension
00139                 LLStringBase<char>::format_map_t args;
00140                 args["[FILE]"] = LLString(short_name + 1);
00141                 gViewerWindow->alertXml("NoFileExtension", args);
00142                 return NULL;
00143         }
00144         else
00145         {
00146                 //so there is an extension
00147                 //loop over the valid extensions and compare to see
00148                 //if the extension is valid
00149 
00150                 //now grab the set of valid file extensions
00151                 const char* valids = build_extensions_string(type);
00152                 std::string valid_extensions = std::string(valids);
00153 
00154                 BOOL ext_valid = FALSE;
00155                 
00156                 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
00157                 boost::char_separator<char> sep(" ");
00158                 tokenizer tokens(valid_extensions, sep);
00159                 tokenizer::iterator token_iter;
00160 
00161                 //now loop over all valid file extensions
00162                 //and compare them to the extension of the file
00163                 //to be uploaded
00164                 for( token_iter = tokens.begin();
00165                          token_iter != tokens.end() && ext_valid != TRUE;
00166                          ++token_iter)
00167                 {
00168                         const char* cur_token = token_iter->c_str();
00169 
00170                         if (0 == strnicmp(cur_token, ext, strlen(cur_token)) ||         /* Flawfinder: ignore */
00171                                 0 == strnicmp(cur_token, "*.*", strlen(cur_token)))             /* Flawfinder: ignore */
00172                         {
00173                                 //valid extension
00174                                 //or the acceptable extension is any
00175                                 ext_valid = TRUE;
00176                         }
00177                 }//end for (loop over all tokens)
00178 
00179                 if (ext_valid == FALSE)
00180                 {
00181                         //should only get here if the extension exists
00182                         //but is invalid
00183                         LLStringBase<char>::format_map_t args;
00184                         args["[EXTENSION]"] = ext;
00185                         args["[VALIDS]"] = valids;
00186                         gViewerWindow->alertXml("InvalidFileExtension", args);
00187                         return NULL;
00188                 }
00189         }//end else (non-null extension)
00190 
00191         //valid file extension
00192         
00193         //now we check to see
00194         //if the file is actually a valid image/sound/etc.
00195         if (type == LLFilePicker::FFLOAD_WAV)
00196         {
00197                 // pre-qualify wavs to make sure the format is acceptable
00198                 char error_msg[MAX_STRING];             /* Flawfinder: ignore */        
00199                 if (check_for_invalid_wav_formats(filename,error_msg))
00200                 {
00201                         llinfos << error_msg << ": " << filename << llendl;
00202                         LLStringBase<char>::format_map_t args;
00203                         args["[FILE]"] = filename;
00204                         gViewerWindow->alertXml( error_msg, args );
00205                         return NULL;
00206                 }
00207         }//end if a wave/sound file
00208 
00209         
00210         return filename;
00211 }
00212 
00213 class LLFileUploadImage : public view_listener_t
00214 {
00215         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00216         {
00217                 const char* filename = upload_pick((void *)LLFilePicker::FFLOAD_IMAGE);
00218                 if (filename)
00219                 {
00220                         LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename);
00221                         LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_image_preview.xml");
00222                 }
00223                 return TRUE;
00224         }
00225 };
00226 
00227 class LLFileUploadSound : public view_listener_t
00228 {
00229         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00230         {
00231                 const char* filename = upload_pick((void*)LLFilePicker::FFLOAD_WAV);
00232                 if (filename)
00233                 {
00234                         LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
00235                         LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_sound_preview.xml");
00236                 }
00237                 return true;
00238         }
00239 };
00240 
00241 class LLFileUploadAnim : public view_listener_t
00242 {
00243         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00244         {
00245                 const char* filename = upload_pick((void*)LLFilePicker::FFLOAD_ANIM);
00246                 if (filename)
00247                 {
00248                         LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename);
00249                         LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_animation_preview.xml");
00250                 }
00251                 return true;
00252         }
00253 };
00254 
00255 class LLFileUploadBulk : public view_listener_t
00256 {
00257         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00258         {
00259                 if( gAgent.cameraMouselook() )
00260                 {
00261                         gAgent.changeCameraToDefault();
00262                 }
00263 
00264                 // TODO:
00265                 // Iterate over all files
00266                 // Check extensions for uploadability, cost
00267                 // Check user balance for entire cost
00268                 // Charge user entire cost
00269                 // Loop, uploading
00270                 // If an upload fails, refund the user for that one
00271                 //
00272                 // Also fix single upload to charge first, then refund
00273 
00274                 LLFilePicker& picker = LLFilePicker::instance();
00275                 if (picker.getMultipleOpenFiles())
00276                 {
00277                         const char* filename = picker.getFirstFile();
00278                         const char* name = picker.getDirname();
00279 
00280                         LLString asset_name = name;
00281                         LLString::replaceNonstandardASCII( asset_name, '?' );
00282                         LLString::replaceChar(asset_name, '|', '?');
00283                         LLString::stripNonprintable(asset_name);
00284                         LLString::trim(asset_name);
00285 
00286                         char* asset_name_str = (char*)asset_name.c_str();
00287                         char* end_p = strrchr(asset_name_str, '.');              // strip extension if exists
00288                         if( !end_p )
00289                         {
00290                                 end_p = asset_name_str + strlen( asset_name_str );              /* Flawfinder: ignore */
00291                         }
00292                                 
00293                         S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
00294 
00295                         asset_name = asset_name.substr( 0, len );
00296 
00297                         upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file
00298                 }
00299                 else
00300                 {
00301                         llinfos << "Couldn't import objects from file" << llendl;
00302                 }
00303                 return true;
00304         }
00305 };
00306 
00307 void upload_error(const char* error_message, const char* label, const std::string filename, const LLStringBase<char>::format_map_t args) 
00308 {
00309         llwarns << error_message << llendl;
00310         gViewerWindow->alertXml(label, args);
00311         if(remove(filename.c_str()) == -1)
00312         {
00313                 lldebugs << "unable to remove temp file" << llendl;
00314         }
00315         LLFilePicker::instance().reset();                                               
00316 }
00317 
00318 class LLFileEnableCloseWindow : public view_listener_t
00319 {
00320         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00321         {
00322                 bool new_value = gFloaterView->getFocusedFloater() != NULL || gSnapshotFloaterView->getFocusedFloater() != NULL;
00323                 // horrendously opaque, this code
00324                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
00325                 return true;
00326         }
00327 };
00328 
00329 class LLFileCloseWindow : public view_listener_t
00330 {
00331         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00332         {
00333                 LLFloater::closeFocusedFloater();
00334 
00335                 return true;
00336         }
00337 };
00338 
00339 class LLFileEnableCloseAllWindows : public view_listener_t
00340 {
00341         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00342         {
00343                 bool open_children = gFloaterView->allChildrenClosed();
00344                 gMenuHolder->findControl(userdata["control"].asString())->setValue(!open_children);
00345                 return true;
00346         }
00347 };
00348 
00349 class LLFileCloseAllWindows : public view_listener_t
00350 {
00351         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00352         {
00353                 bool app_quitting = false;
00354                 gFloaterView->closeAllChildren(app_quitting);
00355 
00356                 return true;
00357         }
00358 };
00359 
00360 class LLFileSaveTexture : public view_listener_t
00361 {
00362         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00363         {
00364                 LLFloater* top = gFloaterView->getFrontmost();
00365                 if (top)
00366                 {
00367                         top->saveAs();
00368                 }
00369                 return true;
00370         }
00371 };
00372 
00373 class LLFileTakeSnapshot : public view_listener_t
00374 {
00375         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00376         {
00377                 LLFloaterSnapshot::show(NULL);
00378                 return true;
00379         }
00380 };
00381 
00382 class LLFileTakeSnapshotToDisk : public view_listener_t
00383 {
00384         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00385         {
00386                 LLPointer<LLImageRaw> raw = new LLImageRaw;
00387 
00388                 S32 width = gViewerWindow->getWindowDisplayWidth();
00389                 S32 height = gViewerWindow->getWindowDisplayHeight();
00390 
00391                 if (gSavedSettings.getBOOL("HighResSnapshot"))
00392                 {
00393                         width *= 2;
00394                         height *= 2;
00395                 }
00396 
00397                 if (gViewerWindow->rawSnapshot(raw,
00398                                                                            width,
00399                                                                            height,
00400                                                                            TRUE,
00401                                                                            FALSE,
00402                                                                            gSavedSettings.getBOOL("RenderUIInSnapshot"),
00403                                                                            FALSE))
00404                 {
00405                         if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
00406                         {
00407                                 gViewerWindow->playSnapshotAnimAndSound();
00408                         }
00409                         LLImageBase::setSizeOverride(TRUE);
00410                         gViewerWindow->saveImageNumbered(raw);
00411                         LLImageBase::setSizeOverride(FALSE);
00412                 }
00413                 return true;
00414         }
00415 };
00416 
00417 class LLFileQuit : public view_listener_t
00418 {
00419         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
00420         {
00421                 LLAppViewer::instance()->userQuit();
00422                 return true;
00423         }
00424 };
00425 
00426 void handle_upload(void* data)
00427 {
00428         const char* filename = upload_pick(data);
00429         if (filename)
00430         {
00431                 LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
00432                 LLUICtrlFactory::getInstance()->buildFloater(floaterp, "floater_name_description.xml");
00433         }
00434 }
00435 
00436 void handle_compress_image(void*)
00437 {
00438         LLFilePicker& picker = LLFilePicker::instance();
00439         if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE))
00440         {
00441                 const char* input_file = picker.getFirstFile();
00442                 while (input_file)
00443                 {
00444                         std::string infile(input_file);
00445                         std::string outfile = infile + ".j2c";
00446 
00447                         llinfos << "Input:  " << infile << llendl;
00448                         llinfos << "Output: " << outfile << llendl;
00449 
00450                         BOOL success;
00451 
00452                         success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
00453 
00454                         if (success)
00455                         {
00456                                 llinfos << "Compression complete" << llendl;
00457                         }
00458                         else
00459                         {
00460                                 llinfos << "Compression failed: " << LLImageBase::getLastError() << llendl;
00461                         }
00462 
00463                         input_file = picker.getNextFile();
00464                 }
00465         }
00466 }
00467 
00468 void upload_new_resource(const LLString& src_filename, std::string name,
00469                                                  std::string desc, S32 compression_info,
00470                                                  LLAssetType::EType destination_folder_type,
00471                                                  LLInventoryType::EType inv_type,
00472                                                  U32 next_owner_perm,
00473                                                  const LLString& display_name,
00474                                                  LLAssetStorage::LLStoreAssetCallback callback,
00475                                                  void *userdata)
00476 {       
00477         // Generate the temporary UUID.
00478         LLString filename = gDirUtilp->getTempFilename();
00479         LLTransactionID tid;
00480         LLAssetID uuid;
00481         
00482         LLStringBase<char>::format_map_t args;
00483 
00484         LLString ext = src_filename.substr(src_filename.find_last_of('.'));
00485         LLAssetType::EType asset_type = LLAssetType::AT_NONE;
00486         char error_message[MAX_STRING];         /* Flawfinder: ignore */        
00487         error_message[0] = '\0';
00488         LLString temp_str;
00489 
00490         BOOL error = FALSE;
00491         
00492         if (ext.empty())
00493         {
00494                 LLString::size_type offset = filename.find_last_of(gDirUtilp->getDirDelimiter());
00495                 if (offset != LLString::npos)
00496                         offset++;
00497                 LLString short_name = filename.substr(offset);
00498                 
00499                 // No extension
00500                 snprintf(error_message,         /* Flawfinder: ignore */
00501                                 MAX_STRING,
00502                                 "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
00503                                 short_name.c_str());
00504                 args["[FILE]"] = short_name;
00505                 upload_error(error_message, "NofileExtension", filename, args);
00506                 return;
00507         }
00508         else if( LLString::compareInsensitive(ext.c_str(),".bmp") == 0 )
00509         {
00510                 asset_type = LLAssetType::AT_TEXTURE;
00511                 if (!LLViewerImageList::createUploadFile(src_filename,
00512                                                                                                  filename,
00513                                                                                                  IMG_CODEC_BMP ))
00514                 {
00515                         snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n",            /* Flawfinder: ignore */
00516                                         src_filename.c_str(), LLImageBase::getLastError().c_str());
00517                         args["[FILE]"] = src_filename;
00518                         args["[ERROR]"] = LLImageBase::getLastError();
00519                         upload_error(error_message, "ProblemWithFile", filename, args);
00520                         return;
00521                 }
00522         }
00523         else if( LLString::compareInsensitive(ext.c_str(),".tga") == 0 )
00524         {
00525                 asset_type = LLAssetType::AT_TEXTURE;
00526                 if (!LLViewerImageList::createUploadFile(src_filename,
00527                                                                                                  filename,
00528                                                                                                  IMG_CODEC_TGA ))
00529                 {
00530                         snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n",            /* Flawfinder: ignore */
00531                                         src_filename.c_str(), LLImageBase::getLastError().c_str());
00532                         args["[FILE]"] = src_filename;
00533                         args["[ERROR]"] = LLImageBase::getLastError();
00534                         upload_error(error_message, "ProblemWithFile", filename, args);
00535                         return;
00536                 }
00537         }
00538         else if( LLString::compareInsensitive(ext.c_str(),".jpg") == 0 || LLString::compareInsensitive(ext.c_str(),".jpeg") == 0)
00539         {
00540                 asset_type = LLAssetType::AT_TEXTURE;
00541                 if (!LLViewerImageList::createUploadFile(src_filename,
00542                                                                                                  filename,
00543                                                                                                  IMG_CODEC_JPEG ))
00544                 {
00545                         snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n",            /* Flawfinder: ignore */
00546                                         src_filename.c_str(), LLImageBase::getLastError().c_str());
00547                         args["[FILE]"] = src_filename;
00548                         args["[ERROR]"] = LLImageBase::getLastError();
00549                         upload_error(error_message, "ProblemWithFile", filename, args);
00550                         return;
00551                 }
00552         }
00553         else if( LLString::compareInsensitive(ext.c_str(),".png") == 0 )
00554         {
00555                 asset_type = LLAssetType::AT_TEXTURE;
00556                 if (!LLViewerImageList::createUploadFile(src_filename,
00557                                                                                                  filename,
00558                                                                                                  IMG_CODEC_PNG ))
00559                 {
00560                         sprintf(error_message, "Problem with file %s:\n\n%s\n",
00561                                         src_filename.c_str(), LLImageBase::getLastError().c_str());
00562                         args["[FILE]"] = src_filename;
00563                         args["[ERROR]"] = LLImageBase::getLastError();
00564                         upload_error(error_message, "ProblemWithFile", filename, args);
00565                         return;
00566                 }
00567         }
00568         else if(LLString::compareInsensitive(ext.c_str(),".wav") == 0)
00569         {
00570                 asset_type = LLAssetType::AT_SOUND;  // tag it as audio
00571                 S32 encode_result = 0;
00572 
00573                 llinfos << "Attempting to encode wav as an ogg file" << llendl;
00574 
00575                 encode_result = encode_vorbis_file(src_filename.c_str(), filename.c_str());
00576                 
00577                 if (LLVORBISENC_NOERR != encode_result)
00578                 {
00579                         switch(encode_result)
00580                         {
00581                                 case LLVORBISENC_DEST_OPEN_ERR:
00582                     snprintf(error_message, MAX_STRING, "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str());           /* Flawfinder: ignore */
00583                                         args["[FILE]"] = filename;
00584                                         upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args);
00585                                         break;
00586 
00587                                 default:        
00588                                   snprintf(error_message, MAX_STRING, "Unknown vorbis encode failure on: %s\n", src_filename.c_str());          /* Flawfinder: ignore */
00589                                         args["[FILE]"] = src_filename;
00590                                         upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args);
00591                                         break;  
00592                         }       
00593                         return;
00594                 }
00595         }
00596         else if(LLString::compareInsensitive(ext.c_str(),".tmp") == 0)          
00597         {               
00598                 // This is a generic .lin resource file         
00599          asset_type = LLAssetType::AT_OBJECT;           
00600          LLFILE* in = LLFile::fopen(src_filename.c_str(), "rb");                /* Flawfinder: ignore */                
00601          if (in)                
00602          {              
00603                  // read in the file header             
00604                  char buf[16384];               /* Flawfinder: ignore */        
00605                  S32 read;              /* Flawfinder: ignore */                
00606                  S32  version;          
00607                  if (fscanf(in, "LindenResource\nversion %d\n", &version))              
00608                  {              
00609                          if (2 == version)              
00610                          {
00611                                                                 // *NOTE: This buffer size is hard coded into scanf() below.
00612                                  char label[MAX_STRING];                /* Flawfinder: ignore */                
00613                                  char value[MAX_STRING];                /* Flawfinder: ignore */                
00614                                  S32  tokens_read;              
00615                                  while (fgets(buf, 1024, in))           
00616                                  {              
00617                                          label[0] = '\0';               
00618                                          value[0] = '\0';               
00619                                          tokens_read = sscanf(  /* Flawfinder: ignore */
00620                                                                                          buf,
00621                                                                                          "%254s %254s\n",
00622                                                                                          label, value);         
00623 
00624                                          llinfos << "got: " << label << " = " << value          
00625                                                          << llendl;             
00626 
00627                                          if (EOF == tokens_read)                
00628                                          {              
00629                                                  fclose(in);            
00630                                                  snprintf(error_message, MAX_STRING, "corrupt resource file: %s", src_filename.c_str());                /* Flawfinder: ignore */
00631                                                                                                  args["[FILE]"] = src_filename;
00632                                                                                                  upload_error(error_message, "CorruptResourceFile", filename, args);
00633                                                  return;
00634                                          }              
00635 
00636                                          if (2 == tokens_read)          
00637                                          {              
00638                                                  if (! strcmp("type", label))           
00639                                                  {              
00640                                                          asset_type = (LLAssetType::EType)(atoi(value));                
00641                                                  }              
00642                                          }              
00643                                          else           
00644                                          {              
00645                                                  if (! strcmp("_DATA_", label))         
00646                                                  {              
00647                                                          // below is the data section           
00648                                                          break;         
00649                                                  }              
00650                                          }              
00651                                          // other values are currently discarded                
00652                                  }              
00653 
00654                          }              
00655                          else           
00656                          {              
00657                                  fclose(in);            
00658                                  snprintf(error_message, MAX_STRING, "unknown linden resource file version in file: %s", src_filename.c_str());         /* Flawfinder: ignore */
00659                                                                  args["[FILE]"] = src_filename;
00660                                                                  upload_error(error_message, "UnknownResourceFileVersion", filename, args);
00661                                  return;
00662                          }              
00663                  }              
00664                  else           
00665                  {              
00666                          // this is an original binary formatted .lin file              
00667                          // start over at the beginning of the file             
00668                          fseek(in, 0, SEEK_SET);                
00669 
00670                          const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256;          
00671                          const S32 MAX_ASSET_NAME_LENGTH = 64;          
00672                          S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH;           
00673                          S16     type_num;              
00674 
00675                          // read in and throw out most of the header except for the type                
00676                          if (fread(buf, header_size, 1, in) != 1)
00677                                                  {
00678                                                          llwarns << "Short read" << llendl;
00679                                                  }
00680                          memcpy(&type_num, buf + 16, sizeof(S16));              /* Flawfinder: ignore */                
00681                          asset_type = (LLAssetType::EType)type_num;             
00682                  }              
00683 
00684                  // copy the file's data segment into another file for uploading                
00685                  LLFILE* out = LLFile::fopen(filename.c_str(), "wb");           /* Flawfinder: ignore */        
00686                  if (out)               
00687                  {              
00688                          while((read = fread(buf, 1, 16384, in)))               /* Flawfinder: ignore */                
00689                          {              
00690                                                          if (fwrite(buf, 1, read, out) != read)
00691                                                          {
00692                                                                  llwarns << "Short write" << llendl;
00693                                                          }
00694                          }              
00695                          fclose(out);           
00696                  }              
00697                  else           
00698                  {              
00699                          fclose(in);            
00700                          snprintf(error_message, MAX_STRING, "Unable to create output file: %s", filename.c_str());             /* Flawfinder: ignore */
00701                                                  args["[FILE]"] = filename;
00702                                                  upload_error(error_message, "UnableToCreateOutputFile", filename, args);
00703                          return;
00704                  }              
00705 
00706                  fclose(in);            
00707          }              
00708          else           
00709          {              
00710                  llinfos << "Couldn't open .lin file " << src_filename << llendl;               
00711          }              
00712         }
00713         else if (LLString::compareInsensitive(ext.c_str(),".bvh") == 0)
00714         {
00715                 snprintf(error_message, MAX_STRING, "We do not currently support bulk upload of animation files\n");            /* Flawfinder: ignore */
00716                 upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args);
00717                 return;
00718         }
00719         else
00720         {
00721                 // Unknown extension
00722                 snprintf(error_message, MAX_STRING, "Unknown file extension %s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", ext.c_str());         /* Flawfinder: ignore */
00723                 error = TRUE;;
00724         }
00725 
00726         // gen a new transaction ID for this asset
00727         tid.generate();
00728 
00729         if (!error)
00730         {
00731                 uuid = tid.makeAssetID(gAgent.getSecureSessionID());
00732                 // copy this file into the vfs for upload
00733                 S32 file_size;
00734                 apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size);
00735                 if (fp)
00736                 {
00737                         LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
00738 
00739                         file.setMaxSize(file_size);
00740 
00741                         const S32 buf_size = 65536;
00742                         U8 copy_buf[buf_size];
00743                         while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size)))
00744                         {
00745                                 file.write(copy_buf, file_size);
00746                         }
00747                         apr_file_close(fp);
00748                 }
00749                 else
00750                 {
00751                         snprintf(error_message, MAX_STRING, "Unable to access output file: %s", filename.c_str());              /* Flawfinder: ignore */
00752                         error = TRUE;
00753                 }
00754         }
00755 
00756         if (!error)
00757         {
00758                 LLString t_disp_name = display_name;
00759                 if (t_disp_name.empty())
00760                 {
00761                         t_disp_name = src_filename;
00762                 }
00763                 upload_new_resource(tid, asset_type, name, desc, compression_info, // tid
00764                                                         destination_folder_type, inv_type, next_owner_perm,
00765                                                         display_name, callback, userdata);
00766         }
00767         else
00768         {
00769                 llwarns << error_message << llendl;
00770                 LLStringBase<char>::format_map_t args;
00771                 args["[ERROR_MESSAGE]"] = error_message;
00772                 gViewerWindow->alertXml("ErrorMessage", args);
00773                 if(LLFile::remove(filename.c_str()) == -1)
00774                 {
00775                         lldebugs << "unable to remove temp file" << llendl;
00776                 }
00777                 LLFilePicker::instance().reset();
00778         }
00779 }
00780 
00781 void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed)
00782 {
00783         LLResourceData* data = (LLResourceData*)user_data;
00784         //LLAssetType::EType pref_loc = data->mPreferredLocation;
00785         BOOL is_balance_sufficient = TRUE;
00786         if(result >= 0)
00787         {
00788                 LLAssetType::EType dest_loc = (data->mPreferredLocation == LLAssetType::AT_NONE) ? data->mAssetInfo.mType : data->mPreferredLocation;
00789 
00790                 if (LLAssetType::AT_SOUND == data->mAssetInfo.mType ||
00791                         LLAssetType::AT_TEXTURE == data->mAssetInfo.mType ||
00792                         LLAssetType::AT_ANIMATION == data->mAssetInfo.mType)
00793                 {
00794                         // Charge the user for the upload.
00795                         LLViewerRegion* region = gAgent.getRegion();
00796                         S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
00797 
00798                         if(!(can_afford_transaction(upload_cost)))
00799                         {
00800                                 LLFloaterBuyCurrency::buyCurrency(
00801                                         llformat("Uploading %s costs",
00802                                                 data->mAssetInfo.getName().c_str()),
00803                                         upload_cost);
00804                                 is_balance_sufficient = FALSE;
00805                         }
00806                         else if(region)
00807                         {
00808                                 // Charge user for upload
00809                                 gStatusBar->debitBalance(upload_cost);
00810                                 
00811                                 LLMessageSystem* msg = gMessageSystem;
00812                                 msg->newMessageFast(_PREHASH_MoneyTransferRequest);
00813                                 msg->nextBlockFast(_PREHASH_AgentData);
00814                                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00815                                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00816                                 msg->nextBlockFast(_PREHASH_MoneyData);
00817                                 msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID());
00818                                 msg->addUUIDFast(_PREHASH_DestID, LLUUID::null);
00819                                 msg->addU8("Flags", 0);
00820                                 msg->addS32Fast(_PREHASH_Amount, upload_cost);
00821                                 msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
00822                                 msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
00823                                 msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE);
00824                                 msg->addStringFast(_PREHASH_Description, NULL);
00825                                 msg->sendReliable(region->getHost());
00826                         }
00827                 }
00828 
00829                 if(is_balance_sufficient)
00830                 {
00831                         // Actually add the upload to inventory
00832                         llinfos << "Adding " << uuid << " to inventory." << llendl;
00833                         LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc));
00834                         if(folder_id.notNull())
00835                         {
00836                                 U32 next_owner_perm = data->mNextOwnerPerm;
00837                                 if(PERM_NONE == next_owner_perm)
00838                                 {
00839                                         next_owner_perm = PERM_MOVE | PERM_TRANSFER;
00840                                 }
00841                                 create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
00842                                         folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
00843                                         data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
00844                                         data->mInventoryType, NOT_WEARABLE, next_owner_perm,
00845                                         LLPointer<LLInventoryCallback>(NULL));
00846                         }
00847                         else
00848                         {
00849                                 llwarns << "Can't find a folder to put it in" << llendl;
00850                         }
00851                 }
00852         }
00853         else //         if(result >= 0)
00854         {
00855                 LLStringBase<char>::format_map_t args;
00856                 args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
00857                 args["[REASON]"] = LLString(LLAssetStorage::getErrorString(result));
00858                 gViewerWindow->alertXml("CannotUploadReason", args);
00859         }
00860 
00861         LLUploadDialog::modalUploadFinished();
00862         delete data;
00863 
00864         // *NOTE: This is a pretty big hack. What this does is check the
00865         // file picker if there are any more pending uploads. If so,
00866         // upload that file.
00867         const char* next_file = LLFilePicker::instance().getNextFile();
00868         if(is_balance_sufficient && next_file)
00869         {
00870                 const char* name = LLFilePicker::instance().getDirname();
00871 
00872                 LLString asset_name = name;
00873                 LLString::replaceNonstandardASCII( asset_name, '?' );
00874                 LLString::replaceChar(asset_name, '|', '?');
00875                 LLString::stripNonprintable(asset_name);
00876                 LLString::trim(asset_name);
00877 
00878                 char* asset_name_str = (char*)asset_name.c_str();
00879                 char* end_p = strrchr(asset_name_str, '.');              // strip extension if exists
00880                 if( !end_p )
00881                 {
00882                         end_p = asset_name_str + strlen( asset_name_str );              /* Flawfinder: ignore */
00883                 }
00884                         
00885                 S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
00886 
00887                 asset_name = asset_name.substr( 0, len );
00888 
00889                 upload_new_resource(next_file, asset_name, asset_name,  // file
00890                                                         0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
00891         }
00892 }
00893 
00894 void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type,
00895                                                  std::string name,
00896                                                  std::string desc, S32 compression_info,
00897                                                  LLAssetType::EType destination_folder_type,
00898                                                  LLInventoryType::EType inv_type,
00899                                                  U32 next_owner_perm,
00900                                                  const LLString& display_name,
00901                                                  LLAssetStorage::LLStoreAssetCallback callback,
00902                                                  void *userdata)
00903 {
00904         LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
00905         
00906         if( LLAssetType::AT_SOUND == asset_type )
00907         {
00908                 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
00909         }
00910         else
00911         if( LLAssetType::AT_TEXTURE == asset_type )
00912         {
00913                 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
00914         }
00915         else
00916         if( LLAssetType::AT_ANIMATION == asset_type)
00917         {
00918                 LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
00919         }
00920 
00921         if(LLInventoryType::IT_NONE == inv_type)
00922         {
00923                 inv_type = LLInventoryType::defaultForAssetType(asset_type);
00924         }
00925         LLString::stripNonprintable(name);
00926         LLString::stripNonprintable(desc);
00927         if(name.empty())
00928         {
00929                 name = "(No Name)";
00930         }
00931         if(desc.empty())
00932         {
00933                 desc = "(No Description)";
00934         }
00935         
00936         // At this point, we're ready for the upload.
00937         LLString upload_message = "Uploading...\n\n";
00938         upload_message.append(display_name);
00939         LLUploadDialog::modalUploadDialog(upload_message);
00940 
00941         llinfos << "*** Uploading: " << llendl;
00942         llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
00943         llinfos << "UUID: " << uuid << llendl;
00944         llinfos << "Name: " << name << llendl;
00945         llinfos << "Desc: " << desc << llendl;
00946         lldebugs << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type) << llendl;
00947         lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
00948         std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
00949         if (!url.empty())
00950         {
00951                 llinfos << "New Agent Inventory via capability" << llendl;
00952                 LLSD body;
00953                 body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type);
00954                 body["asset_type"] = LLAssetType::lookup(asset_type);
00955                 body["inventory_type"] = LLInventoryType::lookup(inv_type);
00956                 body["name"] = name;
00957                 body["description"] = desc;
00958                 
00959                 std::ostringstream llsdxml;
00960                 LLSDSerialize::toXML(body, llsdxml);
00961                 lldebugs << "posting body to capability: " << llsdxml.str() << llendl;
00962                 LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));
00963         }
00964         else
00965         {
00966                 llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl;
00967                 // check for adequate funds
00968                 // TODO: do this check on the sim
00969                 if (LLAssetType::AT_SOUND == asset_type ||
00970                         LLAssetType::AT_TEXTURE == asset_type ||
00971                         LLAssetType::AT_ANIMATION == asset_type)
00972                 {
00973                         S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
00974                         S32 balance = gStatusBar->getBalance();
00975                         if (balance < upload_cost)
00976                         {
00977                                 // insufficient funds, bail on this upload
00978                                 LLFloaterBuyCurrency::buyCurrency("Uploading costs", upload_cost);
00979                                 return;
00980                         }
00981                 }
00982 
00983                 LLResourceData* data = new LLResourceData;
00984                 data->mAssetInfo.mTransactionID = tid;
00985                 data->mAssetInfo.mUuid = uuid;
00986                 data->mAssetInfo.mType = asset_type;
00987                 data->mAssetInfo.mCreatorID = gAgentID;
00988                 data->mInventoryType = inv_type;
00989                 data->mNextOwnerPerm = next_owner_perm;
00990                 data->mUserData = userdata;
00991                 data->mAssetInfo.setName(name);
00992                 data->mAssetInfo.setDescription(desc);
00993                 data->mPreferredLocation = destination_folder_type;
00994 
00995                 LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
00996                 if (callback)
00997                 {
00998                         asset_callback = callback;
00999                 }
01000                 gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType,
01001                                                                                 asset_callback,
01002                                                                                 (void*)data,
01003                                                                                 FALSE);
01004         }
01005 }
01006 
01007 
01008 void init_menu_file()
01009 {
01010         (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage");
01011         (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound");
01012         (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim");
01013         (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk");
01014         (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow");
01015         (new LLFileCloseAllWindows())->registerListener(gMenuHolder, "File.CloseAllWindows");
01016         (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow");
01017         (new LLFileEnableCloseAllWindows())->registerListener(gMenuHolder, "File.EnableCloseAllWindows");
01018         (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture");
01019         (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot");
01020         (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk");
01021         (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit");
01022 
01023         (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
01024         (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs");
01025 }

Generated on Fri May 16 08:34:13 2008 for SecondLife by  doxygen 1.5.5