00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "imageids.h"
00035 #include "llassetstorage.h"
00036 #include "lldbstrings.h"
00037 #include "lldir.h"
00038 #include "llquantize.h"
00039
00040 #include "llagent.h"
00041 #include "llassetuploadresponders.h"
00042 #include "llviewerwindow.h"
00043 #include "llfloatercustomize.h"
00044 #include "llinventorymodel.h"
00045 #include "llviewerimagelist.h"
00046 #include "llviewerinventory.h"
00047 #include "llviewerregion.h"
00048 #include "llvoavatar.h"
00049 #include "llwearable.h"
00050
00051
00052 S32 LLWearable::sCurrentDefinitionVersion = 1;
00053
00054
00055 const char* LLWearable::sTypeName[ WT_COUNT ] =
00056 {
00057 "shape",
00058 "skin",
00059 "hair",
00060 "eyes",
00061 "shirt",
00062 "pants",
00063 "shoes",
00064 "socks",
00065 "jacket",
00066 "gloves",
00067 "undershirt",
00068 "underpants",
00069 "skirt"
00070 };
00071
00072
00073 const char* LLWearable::sTypeLabel[ WT_COUNT ] =
00074 {
00075 "Shape",
00076 "Skin",
00077 "Hair",
00078 "Eyes",
00079 "Shirt",
00080 "Pants",
00081 "Shoes",
00082 "Socks",
00083 "Jacket",
00084 "Gloves",
00085 "Undershirt",
00086 "Underpants",
00087 "Skirt"
00088 };
00089
00090
00091
00092 LLAssetType::EType LLWearable::typeToAssetType(EWearableType wearable_type)
00093 {
00094 switch( wearable_type )
00095 {
00096 case WT_SHAPE:
00097 case WT_SKIN:
00098 case WT_HAIR:
00099 case WT_EYES:
00100 return LLAssetType::AT_BODYPART;
00101 case WT_SHIRT:
00102 case WT_PANTS:
00103 case WT_SHOES:
00104 case WT_SOCKS:
00105 case WT_JACKET:
00106 case WT_GLOVES:
00107 case WT_UNDERSHIRT:
00108 case WT_UNDERPANTS:
00109 case WT_SKIRT:
00110 return LLAssetType::AT_CLOTHING;
00111 default:
00112 return LLAssetType::AT_NONE;
00113 }
00114 }
00115
00116
00117 LLWearable::LLWearable(const LLTransactionID& transaction_id) :
00118 mDefinitionVersion(LLWearable::sCurrentDefinitionVersion),
00119 mType(WT_SHAPE)
00120 {
00121 mTransactionID = transaction_id;
00122 mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
00123 }
00124
00125 LLWearable::LLWearable(const LLAssetID& asset_id) :
00126 mDefinitionVersion( LLWearable::sCurrentDefinitionVersion ),
00127 mType(WT_SHAPE)
00128 {
00129 mAssetID = asset_id;
00130 mTransactionID.setNull();
00131 }
00132
00133 LLWearable::~LLWearable()
00134 {
00135 }
00136
00137
00138
00139 EWearableType LLWearable::typeNameToType( const LLString& type_name )
00140 {
00141 for( S32 i = 0; i < WT_COUNT; i++ )
00142 {
00143 if( type_name == LLWearable::sTypeName[ i ] )
00144 {
00145 return (EWearableType)i;
00146 }
00147 }
00148 return WT_INVALID;
00149 }
00150
00151
00152 const char* terse_F32_to_string( F32 f, char s[MAX_STRING] )
00153 {
00154 char* r = s;
00155 S32 len = snprintf( s, MAX_STRING, "%.2f", f );
00156
00157
00158
00159 while( '0' == r[len - 1] )
00160 {
00161 len--;
00162 r[len] = '\0';
00163 }
00164
00165 if( '.' == r[len - 1] )
00166 {
00167
00168 len--;
00169 r[len] = '\0';
00170 }
00171 else
00172 if( ('-' == r[0]) && ('0' == r[1]) )
00173 {
00174
00175 r++;
00176 r[0] = '-';
00177 }
00178 else
00179 if( '0' == r[0] )
00180 {
00181
00182 r++;
00183 }
00184
00185 return r;
00186 }
00187
00188 BOOL LLWearable::exportFile( LLFILE* file )
00189 {
00190
00191 if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
00192 {
00193 return FALSE;
00194 }
00195
00196
00197 if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
00198 {
00199 return FALSE;
00200 }
00201
00202
00203 if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
00204 {
00205 return FALSE;
00206 }
00207
00208
00209 if( !mPermissions.exportFile( file ) )
00210 {
00211 return FALSE;
00212 }
00213
00214
00215 if( !mSaleInfo.exportFile( file ) )
00216 {
00217 return FALSE;
00218 }
00219
00220
00221 S32 type = (S32)mType;
00222 if( fprintf( file, "type %d\n", type ) < 0 )
00223 {
00224 return FALSE;
00225 }
00226
00227
00228 S32 num_parameters = mVisualParamMap.size();
00229 if( fprintf( file, "parameters %d\n", num_parameters ) < 0 )
00230 {
00231 return FALSE;
00232 }
00233
00234 char s[ MAX_STRING ];
00235 for (param_map_t::iterator iter = mVisualParamMap.begin();
00236 iter != mVisualParamMap.end(); ++iter)
00237 {
00238 S32 param_id = iter->first;
00239 F32 param_weight = iter->second;
00240 if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight, s ) ) < 0 )
00241 {
00242 return FALSE;
00243 }
00244 }
00245
00246
00247 S32 num_textures = mTEMap.size();
00248 if( fprintf( file, "textures %d\n", num_textures ) < 0 )
00249 {
00250 return FALSE;
00251 }
00252
00253 for (te_map_t::iterator iter = mTEMap.begin();
00254 iter != mTEMap.end(); ++iter)
00255 {
00256 S32 te = iter->first;
00257 LLUUID& image_id = iter->second;
00258 if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
00259 {
00260 return FALSE;
00261 }
00262 }
00263
00264 return TRUE;
00265 }
00266
00267
00268
00269 BOOL LLWearable::importFile( LLFILE* file )
00270 {
00271
00272
00273
00274 char text_buffer[2048];
00275 S32 fields_read = 0;
00276
00277
00278 fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
00279 if( fields_read != 1 )
00280 {
00281
00282
00283 llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
00284
00285 return FALSE;
00286 }
00287
00288 if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion )
00289 {
00290 llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
00291 return FALSE;
00292 }
00293
00294
00295 char next_char = fgetc( file );
00296 if( '\n' == next_char )
00297 {
00298
00299 mName = "";
00300 }
00301 else
00302 {
00303 ungetc( next_char, file );
00304 fields_read = fscanf(
00305 file,
00306 "%2047[^\n]",
00307 text_buffer);
00308 if( (1 != fields_read) || (fgetc( file ) != '\n') )
00309 {
00310 llwarns << "Bad Wearable asset: early end of file" << llendl;
00311 return FALSE;
00312 }
00313 mName = text_buffer;
00314 LLString::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
00315 }
00316
00317
00318 next_char = fgetc( file );
00319 if( '\n' == next_char )
00320 {
00321
00322 mDescription = "";
00323 }
00324 else
00325 {
00326 ungetc( next_char, file );
00327 fields_read = fscanf(
00328 file,
00329 "%2047[^\n]",
00330 text_buffer );
00331 if( (1 != fields_read) || (fgetc( file ) != '\n') )
00332 {
00333 llwarns << "Bad Wearable asset: early end of file" << llendl;
00334 return FALSE;
00335 }
00336 mDescription = text_buffer;
00337 LLString::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
00338 }
00339
00340
00341 S32 perm_version;
00342 fields_read = fscanf( file, " permissions %d\n", &perm_version );
00343 if( (fields_read != 1) || (perm_version != 0) )
00344 {
00345 llwarns << "Bad Wearable asset: missing permissions" << llendl;
00346 return FALSE;
00347 }
00348 if( !mPermissions.importFile( file ) )
00349 {
00350 return FALSE;
00351 }
00352
00353
00354 S32 sale_info_version;
00355 fields_read = fscanf( file, " sale_info %d\n", &sale_info_version );
00356 if( (fields_read != 1) || (sale_info_version != 0) )
00357 {
00358 llwarns << "Bad Wearable asset: missing sale_info" << llendl;
00359 return FALSE;
00360 }
00361
00362
00363
00364
00365 BOOL has_perm_mask = FALSE;
00366 U32 perm_mask = 0;
00367 if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) )
00368 {
00369 return FALSE;
00370 }
00371 if(has_perm_mask)
00372 {
00373
00374 if(!(perm_mask & PERM_COPY))
00375 {
00376 perm_mask |= PERM_TRANSFER;
00377 }
00378 mPermissions.setMaskNext(perm_mask);
00379 }
00380
00381
00382 S32 type = -1;
00383 fields_read = fscanf( file, "type %d\n", &type );
00384 if( fields_read != 1 )
00385 {
00386 llwarns << "Bad Wearable asset: bad type" << llendl;
00387 return FALSE;
00388 }
00389 if( 0 <= type && type < WT_COUNT )
00390 {
00391 mType = (EWearableType)type;
00392 }
00393 else
00394 {
00395 llwarns << "Bad Wearable asset: bad type #" << type << llendl;
00396 return FALSE;
00397 }
00398
00399
00400
00401 S32 num_parameters = 0;
00402 fields_read = fscanf( file, "parameters %d\n", &num_parameters );
00403 if( fields_read != 1 )
00404 {
00405 llwarns << "Bad Wearable asset: missing parameters block" << llendl;
00406 return FALSE;
00407 }
00408
00409
00410 S32 i;
00411 for( i = 0; i < num_parameters; i++ )
00412 {
00413 S32 param_id = 0;
00414 F32 param_weight = 0.f;
00415 fields_read = fscanf( file, "%d %f\n", ¶m_id, ¶m_weight );
00416 if( fields_read != 2 )
00417 {
00418 llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
00419 return FALSE;
00420 }
00421 mVisualParamMap[param_id] = param_weight;
00422 }
00423
00424
00425 S32 num_textures = 0;
00426 fields_read = fscanf( file, "textures %d\n", &num_textures);
00427 if( fields_read != 1 )
00428 {
00429 llwarns << "Bad Wearable asset: missing textures block" << llendl;
00430 return FALSE;
00431 }
00432
00433
00434 for( i = 0; i < num_textures; i++ )
00435 {
00436 S32 te = 0;
00437 fields_read = fscanf(
00438 file,
00439 "%d %2047s\n",
00440 &te, text_buffer);
00441 if( fields_read != 2 )
00442 {
00443 llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
00444 return FALSE;
00445 }
00446
00447 if( !LLUUID::validate( text_buffer ) )
00448 {
00449 llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
00450 return FALSE;
00451 }
00452
00453 mTEMap[te] = LLUUID(text_buffer );
00454 }
00455
00456 return TRUE;
00457 }
00458
00459
00460
00461
00462
00463 BOOL LLWearable::isOldVersion()
00464 {
00465 LLVOAvatar* avatar = gAgent.getAvatarObject();
00466 llassert( avatar );
00467 if( !avatar )
00468 {
00469 return FALSE;
00470 }
00471
00472 if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
00473 {
00474 llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
00475 llassert(0);
00476 }
00477
00478 if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
00479 {
00480 return TRUE;
00481 }
00482
00483 S32 param_count = 0;
00484 for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam();
00485 param;
00486 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
00487 {
00488 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00489 {
00490 param_count++;
00491 if( !is_in_map(mVisualParamMap, param->getID() ) )
00492 {
00493 return TRUE;
00494 }
00495 }
00496 }
00497 if( param_count != mVisualParamMap.size() )
00498 {
00499 return TRUE;
00500 }
00501
00502
00503 S32 te_count = 0;
00504 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00505 {
00506 if( LLVOAvatar::getTEWearableType( te ) == mType )
00507 {
00508 te_count++;
00509 if( !is_in_map(mTEMap, te ) )
00510 {
00511 return TRUE;
00512 }
00513 }
00514 }
00515 if( te_count != mTEMap.size() )
00516 {
00517 return TRUE;
00518 }
00519
00520 return FALSE;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530 BOOL LLWearable::isDirty()
00531 {
00532 LLVOAvatar* avatar = gAgent.getAvatarObject();
00533 llassert( avatar );
00534 if( !avatar )
00535 {
00536 return FALSE;
00537 }
00538
00539
00540 for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam();
00541 param;
00542 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
00543 {
00544 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00545 {
00546 F32 weight = get_if_there(mVisualParamMap, param->getID(), param->getDefaultWeight());
00547 weight = llclamp( weight, param->getMinWeight(), param->getMaxWeight() );
00548
00549 U8 a = F32_to_U8( param->getWeight(), param->getMinWeight(), param->getMaxWeight() );
00550 U8 b = F32_to_U8( weight, param->getMinWeight(), param->getMaxWeight() );
00551 if( a != b )
00552 {
00553 return TRUE;
00554 }
00555 }
00556 }
00557
00558 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00559 {
00560 if( LLVOAvatar::getTEWearableType( te ) == mType )
00561 {
00562 LLViewerImage* avatar_image = avatar->getTEImage( te );
00563 if( !avatar_image )
00564 {
00565 llassert( 0 );
00566 continue;
00567 }
00568 const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID( te ) );
00569 if( avatar_image->getID() != image_id )
00570 {
00571 return TRUE;
00572 }
00573 }
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 return FALSE;
00585 }
00586
00587
00588 void LLWearable::setParamsToDefaults()
00589 {
00590 LLVOAvatar* avatar = gAgent.getAvatarObject();
00591 llassert( avatar );
00592 if( !avatar )
00593 {
00594 return;
00595 }
00596
00597 mVisualParamMap.clear();
00598 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00599 {
00600 if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00601 {
00602 mVisualParamMap[param->getID()] = param->getDefaultWeight();
00603 }
00604 }
00605 }
00606
00607 void LLWearable::setTexturesToDefaults()
00608 {
00609 mTEMap.clear();
00610 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00611 {
00612 if( LLVOAvatar::getTEWearableType( te ) == mType )
00613 {
00614 mTEMap[te] = LLVOAvatar::getDefaultTEImageID( te );
00615 }
00616 }
00617 }
00618
00619
00620 void LLWearable::writeToAvatar( BOOL set_by_user )
00621 {
00622 LLVOAvatar* avatar = gAgent.getAvatarObject();
00623 llassert( avatar );
00624 if( !avatar )
00625 {
00626 return;
00627 }
00628
00629 ESex old_sex = avatar->getSex();
00630
00631
00632 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00633 {
00634 if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00635 {
00636 S32 param_id = param->getID();
00637 F32 weight = get_if_there(mVisualParamMap, param_id, param->getDefaultWeight());
00638
00639 if (set_by_user)
00640 {
00641 param->setAnimationTarget(weight, set_by_user);
00642 }
00643 else
00644 {
00645 avatar->setVisualParamWeight( param_id, weight, set_by_user );
00646 }
00647 }
00648 }
00649
00650
00651 if (set_by_user)
00652 {
00653 avatar->startAppearanceAnimation(TRUE, TRUE);
00654 }
00655
00656
00657 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00658 {
00659 if( LLVOAvatar::getTEWearableType( te ) == mType )
00660 {
00661 const LLUUID& image_id = get_if_there(mTEMap, te, LLVOAvatar::getDefaultTEImageID( te ) );
00662 LLViewerImage* image = gImageList.getImage( image_id );
00663 avatar->setLocTexTE( te, image, set_by_user );
00664 }
00665 }
00666
00667 avatar->updateVisualParams();
00668
00669 if( gFloaterCustomize )
00670 {
00671 LLViewerInventoryItem* item;
00672 item = (LLViewerInventoryItem*)gInventory.getItem(gAgent.getWearableItem(mType));
00673 U32 perm_mask = PERM_NONE;
00674 BOOL is_complete = FALSE;
00675 if(item)
00676 {
00677 perm_mask = item->getPermissions().getMaskOwner();
00678 is_complete = item->isComplete();
00679 if(!is_complete)
00680 {
00681 item->fetchFromServer();
00682 }
00683 }
00684 gFloaterCustomize->setWearable(mType, this, perm_mask, is_complete);
00685 LLFloaterCustomize::setCurrentWearableType( mType );
00686 }
00687
00688 ESex new_sex = avatar->getSex();
00689 if( old_sex != new_sex )
00690 {
00691 avatar->updateSexDependentLayerSets( set_by_user );
00692 }
00693
00694 avatar->updateMeshTextures();
00695
00696
00697
00698
00699
00700 }
00701
00702
00703
00704 void LLWearable::removeFromAvatar( EWearableType type, BOOL set_by_user )
00705 {
00706 LLVOAvatar* avatar = gAgent.getAvatarObject();
00707 llassert( avatar );
00708 if( !avatar )
00709 {
00710 return;
00711 }
00712
00713
00714 if( (type == WT_SHAPE) ||
00715 (type == WT_SKIN) ||
00716 (type == WT_HAIR) ||
00717 (type == WT_EYES) )
00718 {
00719 return;
00720 }
00721
00722
00723 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00724 {
00725 if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00726 {
00727 S32 param_id = param->getID();
00728 avatar->setVisualParamWeight( param_id, param->getDefaultWeight(), set_by_user );
00729 }
00730 }
00731
00732
00733 LLViewerImage* image = gImageList.getImage( IMG_DEFAULT_AVATAR );
00734 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00735 {
00736 if( LLVOAvatar::getTEWearableType( te ) == type )
00737 {
00738 avatar->setLocTexTE( te, image, set_by_user );
00739 }
00740 }
00741
00742 if( gFloaterCustomize )
00743 {
00744 gFloaterCustomize->setWearable(type, NULL, PERM_ALL, TRUE);
00745 }
00746
00747 avatar->updateVisualParams();
00748 avatar->updateMeshTextures();
00749
00750
00751
00752
00753
00754 }
00755
00756
00757
00758
00759 void LLWearable::readFromAvatar()
00760 {
00761 LLVOAvatar* avatar = gAgent.getAvatarObject();
00762 llassert( avatar );
00763 if( !avatar )
00764 {
00765 return;
00766 }
00767
00768 mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
00769
00770 mVisualParamMap.clear();
00771 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
00772 {
00773 if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00774 {
00775 mVisualParamMap[param->getID()] = param->getWeight();
00776 }
00777 }
00778
00779 mTEMap.clear();
00780 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00781 {
00782 if( LLVOAvatar::getTEWearableType( te ) == mType )
00783 {
00784 LLViewerImage* image = avatar->getTEImage( te );
00785 if( image )
00786 {
00787 mTEMap[te] = image->getID();
00788 }
00789 }
00790 }
00791
00792
00793
00794
00795
00796 }
00797
00798
00799
00800 void LLWearable::copyDataFrom( LLWearable* src )
00801 {
00802 LLVOAvatar* avatar = gAgent.getAvatarObject();
00803 llassert( avatar );
00804 if( !avatar )
00805 {
00806 return;
00807 }
00808
00809 mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
00810
00811 mName = src->mName;
00812 mDescription = src->mDescription;
00813 mPermissions = src->mPermissions;
00814 mSaleInfo = src->mSaleInfo;
00815 mType = src->mType;
00816
00817
00818 for( LLViewerVisualParam* param = (LLViewerVisualParam*) avatar->getFirstVisualParam();
00819 param;
00820 param = (LLViewerVisualParam*) avatar->getNextVisualParam() )
00821 {
00822 if( (param->getWearableType() == mType) && (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE ) )
00823 {
00824 S32 id = param->getID();
00825 F32 weight = get_if_there(src->mVisualParamMap, id, param->getDefaultWeight() );
00826 mVisualParamMap[id] = weight;
00827 }
00828 }
00829
00830
00831 for( S32 te = 0; te < LLVOAvatar::TEX_NUM_ENTRIES; te++ )
00832 {
00833 if( LLVOAvatar::getTEWearableType( te ) == mType )
00834 {
00835 const LLUUID& image_id = get_if_there(src->mTEMap, te, LLVOAvatar::getDefaultTEImageID( te ) );
00836 mTEMap[te] = image_id;
00837 }
00838 }
00839 }
00840
00841 struct LLWearableSaveData
00842 {
00843 EWearableType mType;
00844 };
00845
00846 void LLWearable::saveNewAsset()
00847 {
00848
00849
00850
00851 char new_asset_id_string[UUID_STR_LENGTH];
00852 mAssetID.toString(new_asset_id_string);
00853 char filename[LL_MAX_PATH];
00854 snprintf(filename, LL_MAX_PATH, "%s.wbl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,new_asset_id_string).c_str());
00855 LLFILE* fp = LLFile::fopen(filename, "wb");
00856 BOOL successful_save = FALSE;
00857 if(fp && exportFile(fp))
00858 {
00859 successful_save = TRUE;
00860 }
00861 if(fp)
00862 {
00863 fclose(fp);
00864 fp = NULL;
00865 }
00866 if(!successful_save)
00867 {
00868 char buffer[2*MAX_STRING];
00869 snprintf(buffer,
00870 sizeof(buffer),
00871 "Unable to save '%s' to wearable file.",
00872 mName.c_str());
00873 llwarns << buffer << llendl;
00874
00875 LLStringBase<char>::format_map_t args;
00876 args["[NAME]"] = mName;
00877 gViewerWindow->alertXml("CannotSaveWearableOutOfSpace", args);
00878 return;
00879 }
00880
00881
00882 if( gAssetStorage )
00883 {
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 LLWearableSaveData* data = new LLWearableSaveData;
00902 data->mType = mType;
00903 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
00904 &LLWearable::onSaveNewAssetComplete,
00905 (void*)data);
00906 }
00907 }
00908
00909
00910 void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status)
00911 {
00912 LLWearableSaveData* data = (LLWearableSaveData*)userdata;
00913 const char* type_name = LLWearable::typeToTypeName(data->mType);
00914 if(0 == status)
00915 {
00916
00917 llinfos << "Saved wearable " << type_name << llendl;
00918 }
00919 else
00920 {
00921 char buffer[2*MAX_STRING];
00922 snprintf(buffer,
00923 sizeof(buffer),
00924 "Unable to save %s to central asset store.",
00925 type_name);
00926 llwarns << buffer << " Status: " << status << llendl;
00927 LLStringBase<char>::format_map_t args;
00928 args["[NAME]"] = type_name;
00929 gViewerWindow->alertXml("CannotSaveToAssetStore", args);
00930 }
00931
00932
00933 char new_asset_id_string[UUID_STR_LENGTH];
00934 new_asset_id.toString(new_asset_id_string);
00935 char src_filename[LL_MAX_PATH];
00936 snprintf(src_filename, LL_MAX_PATH, "%s.wbl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,new_asset_id_string).c_str());
00937 LLFile::remove(src_filename);
00938
00939
00940 delete data;
00941 }
00942
00943 BOOL LLWearable::isMatchedToInventoryItem( LLViewerInventoryItem* item )
00944 {
00945 return
00946 ( mName == item->getName() ) &&
00947 ( mDescription == item->getDescription() ) &&
00948 ( mPermissions == item->getPermissions() ) &&
00949 ( mSaleInfo == item->getSaleInfo() );
00950 }
00951
00952 void LLWearable::dump()
00953 {
00954 llinfos << "wearable " << LLWearable::typeToTypeName( mType ) << llendl;
00955 llinfos << " Name: " << mName << llendl;
00956 llinfos << " Desc: " << mDescription << llendl;
00957
00958
00959
00960 llinfos << " Params:" << llendl;
00961 for (param_map_t::iterator iter = mVisualParamMap.begin();
00962 iter != mVisualParamMap.end(); ++iter)
00963 {
00964 S32 param_id = iter->first;
00965 F32 param_weight = iter->second;
00966 llinfos << " " << param_id << " " << param_weight << llendl;
00967 }
00968
00969 llinfos << " Textures:" << llendl;
00970 for (te_map_t::iterator iter = mTEMap.begin();
00971 iter != mTEMap.end(); ++iter)
00972 {
00973 S32 te = iter->first;
00974 LLUUID& image_id = iter->second;
00975 llinfos << " " << te << " " << image_id << llendl;
00976 }
00977 }
00978
00979