diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 3d3420961..d26b45208 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -182,9 +182,6 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : } mIsBuilt = FALSE; - - mNumCollisionVolumes = 0; - mCollisionVolumes = NULL; } // virtual @@ -294,7 +291,7 @@ LLAvatarAppearance::~LLAvatarAppearance() mJointMap.clear(); clearSkeleton(); - deleteAndClearArray(mCollisionVolumes); + clearCollisionVolumes(); std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer()); mPolyMeshes.clear(); @@ -575,12 +572,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent } else // collision volume { - if (volume_num >= (S32)mNumCollisionVolumes) + if (volume_num >= (S32)mCollisionVolumes.size()) { llwarns << "Too many bones" << llendl; return FALSE; } - joint = (&mCollisionVolumes[volume_num]); + joint = (mCollisionVolumes[volume_num]); joint->setName( info->mName ); } @@ -1250,12 +1247,12 @@ LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_of return LLVector3::zero; } - if (joint_index > mNumCollisionVolumes) + if (joint_index > (S32)mCollisionVolumes.size()) { return LLVector3::zero; } - return mCollisionVolumes[joint_index].getVolumePos(volume_offset); + return mCollisionVolumes[joint_index]->getVolumePos(volume_offset); } //----------------------------------------------------------------------------- @@ -1266,12 +1263,12 @@ LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id) //SNOW-488: As mNumCollisionVolumes is a S32 and we are casting from a U32 to a S32 //to compare we also need to be sure of the wrap around case producing (S32) <0 //or in terms of the U32 an out of bounds index in the array. - if ((S32)volume_id > mNumCollisionVolumes || (S32)volume_id<0) + if ((S32)volume_id > (S32)mCollisionVolumes.size() || (S32)volume_id<0) { return NULL; } - return &mCollisionVolumes[volume_id]; + return mCollisionVolumes[volume_id]; } //----------------------------------------------------------------------------- @@ -1279,9 +1276,9 @@ LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id) //----------------------------------------------------------------------------- S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name) { - for (S32 i = 0; i < mNumCollisionVolumes; i++) + for (S32 i = 0; i < (S32)mCollisionVolumes.size(); i++) { - if (mCollisionVolumes[i].getName() == name) + if (mCollisionVolumes[i]->getName() == name) { return i; } @@ -1530,21 +1527,34 @@ LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_in return mBakedTextureDatas[baked_index].mTexLayerSet; } +void LLAvatarAppearance::clearCollisionVolumes() +{ + std::for_each(mCollisionVolumes.begin(), mCollisionVolumes.end(), + DeletePointer()); + mCollisionVolumes.clear(); +} + //----------------------------------------------------------------------------- // allocateCollisionVolumes() //----------------------------------------------------------------------------- BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num ) { - deleteAndClearArray(mCollisionVolumes); - mNumCollisionVolumes = 0; + mCollisionVolumes.reserve(num); - mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; - if (!mCollisionVolumes) + LLAvatarJointCollisionVolume* cv; + for (U32 i = 0; i < num; ++i) { - return FALSE; + cv = new LLAvatarJointCollisionVolume(); + if (cv) + { + mCollisionVolumes.push_back(cv); + } + else + { + clearCollisionVolumes(); + return false; + } } - - mNumCollisionVolumes = num; return TRUE; } diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index b3a02e410..da4e09b42 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -337,9 +337,9 @@ protected: // Collision volumes //-------------------------------------------------------------------- public: - S32 mNumCollisionVolumes; - LLAvatarJointCollisionVolume* mCollisionVolumes; + std::vector mCollisionVolumes; protected: + void clearCollisionVolumes(); BOOL allocateCollisionVolumes(U32 num); /** Physics diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index aeaf79f33..669c2e5fb 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -647,11 +647,11 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info) for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++) { LLPolyVolumeMorphInfo *volume_info = &(*iter); - for (S32 i = 0; i < avatarp->mNumCollisionVolumes; i++) + for (S32 i = 0; i < (S32)avatarp->mCollisionVolumes.size(); i++) { - if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName) + if (avatarp->mCollisionVolumes[i]->getName() == volume_info->mName) { - mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i], + mVolumeMorphs.push_back(LLPolyVolumeMorph(avatarp->mCollisionVolumes[i], volume_info->mScale, volume_info->mPos)); break; diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index a7d2eac67..e39fa373d 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -206,6 +206,7 @@ namespace return "Unknown"; } +#if LL_LINUX std::string compute_CPUFamilyName(const char* cpu_vendor, int composed_family) { const char* intel_string = "GenuineIntel"; @@ -221,6 +222,7 @@ namespace return "Unknown"; } +#else std::string compute_CPUFamilyName(const char* cpu_vendor, int family, int ext_family) { const char* intel_string = "GenuineIntel"; @@ -239,6 +241,7 @@ namespace } return "Unknown"; } +#endif } // end unnamed namespace diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index 4434ef545..2b0b8af6b 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -905,7 +905,6 @@ AIHTTPTimeoutPolicy const* AIHTTPTimeoutPolicy::getTimeoutPolicyByName(std::stri #define P2(n, b) AIHTTPTimeoutPolicy n##_timeout(#n, b) // Policy name Policy -P(assetUploadResponder); P(assetReportHandler); P(avatarPickerResponder); P(authHandler); @@ -952,7 +951,6 @@ P2(meshPhysicsShapeResponder, connect_30s); P2(meshSkinInfoResponder, connect_30s); P(mimeDiscoveryResponder); P(moderationResponder); -P(newAgentInventoryVariablePriceResponder); P(objectCostResponder); P(physicsFlagsResponder); P(productInfoRequestResponder); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0ea26715c..476d752ea 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7735,6 +7735,17 @@ This should be as low as possible, but too low may break functionality Value 1 + RadarAlertShowDist + + Comment + Show distance in radar announcements. + Persist + 1 + Type + Boolean + Value + 1 + RadarAlertSim Comment diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 16dd0d4e5..178eb094f 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -37,6 +37,7 @@ #include "llagent.h" #include "llcompilequeue.h" #include "llfloaterbuycurrency.h" +#include "statemachine/aifilepicker.h" #include "llinventorydefines.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" @@ -66,8 +67,6 @@ #include "llsdutil.h" #include "llvfs.h" -#include "statemachine/aifilepicker.h" - // When uploading multiple files, don't display any of them when uploading more than this number. static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5; @@ -190,9 +189,10 @@ void on_new_single_inventory_upload_complete( LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type) -: mPostData(post_data), - mVFileID(vfile_id), - mAssetType(asset_type) +: + mPostData(post_data), + mVFileID(vfile_id), + mAssetType(asset_type) { if (!gVFS->getExists(vfile_id, asset_type)) { @@ -207,9 +207,10 @@ LLAssetUploadResponder::LLAssetUploadResponder( const LLSD &post_data, const std::string& file_name, LLAssetType::EType asset_type) -: mPostData(post_data), - mFileName(file_name), - mAssetType(asset_type) +: + mPostData(post_data), + mFileName(file_name), + mAssetType(asset_type) { } @@ -223,7 +224,7 @@ LLAssetUploadResponder::~LLAssetUploadResponder() } // virtual -void LLAssetUploadResponder::httpFailure(void) +void LLAssetUploadResponder::httpFailure() { llinfos << "LLAssetUploadResponder::error " << mStatus << " reason: " << mReason << llendl; @@ -248,15 +249,21 @@ void LLAssetUploadResponder::httpFailure(void) } //virtual -void LLAssetUploadResponder::httpSuccess(void) +void LLAssetUploadResponder::httpSuccess() { + const LLSD& content = getContent(); + if (!content.isMap()) + { + failureResult(HTTP_INTERNAL_ERROR_OTHER, "Malformed response contents", content); + return; + } lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl; - std::string state = mContent["state"]; + const std::string& state = content["state"].asString(); if (state == "upload") { - uploadUpload(mContent); + uploadUpload(content); } else if (state == "complete") { @@ -264,20 +271,20 @@ void LLAssetUploadResponder::httpSuccess(void) if (mFileName.empty()) { // rename the file in the VFS to the actual asset id - // llinfos << "Changing uploaded asset UUID to " << mContent["new_asset"].asUUID() << llendl; - gVFS->renameFile(mVFileID, mAssetType, mContent["new_asset"].asUUID(), mAssetType); + // LL_INFOS() << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << LL_ENDL; + gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType); } - uploadComplete(mContent); + uploadComplete(content); } else { - uploadFailure(mContent); + uploadFailure(content); } } void LLAssetUploadResponder::uploadUpload(const LLSD& content) { - std::string uploader = content["uploader"]; + const std::string& uploader = content["uploader"].asString(); if (mFileName.empty()) { LLHTTPClient::postFile(uploader, mVFileID, mAssetType, this); @@ -293,7 +300,7 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content) // remove the "Uploading..." message LLUploadDialog::modalUploadFinished(); - std::string reason = content["state"]; + const std::string& reason = content["state"].asString(); // deal with L$ errors if (reason == "insufficient funds") { @@ -316,10 +323,8 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content) LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, - LLAssetType::EType asset_type, - void (*callback)(bool, void*), - void* user_data) - : LLAssetUploadResponder(post_data, vfile_id, asset_type), mCallBack(callback), mUserData(user_data) + LLAssetType::EType asset_type) + : LLAssetUploadResponder(post_data, vfile_id, asset_type) { } @@ -327,17 +332,13 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type) - : LLAssetUploadResponder(post_data, file_name, asset_type), mCallBack(NULL), mUserData(NULL) + : LLAssetUploadResponder(post_data, file_name, asset_type) { } // virtual -void LLNewAgentInventoryResponder::httpFailure(void) +void LLNewAgentInventoryResponder::httpFailure() { - if (mCallBack) - { - (*mCallBack)(false, mUserData); - } LLAssetUploadResponder::httpFailure(); //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE); } @@ -346,10 +347,6 @@ void LLNewAgentInventoryResponder::httpFailure(void) //virtual void LLNewAgentInventoryResponder::uploadFailure(const LLSD& content) { - if (mCallBack) - { - (*mCallBack)(false, mUserData); - } LLAssetUploadResponder::uploadFailure(content); //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], FALSE); @@ -360,14 +357,9 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) { lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; - if (mCallBack) - { - (*mCallBack)(true, mUserData); - } - //std::ostringstream llsdxml; //LLSDSerialize::toXML(content, llsdxml); - //llinfos << "upload complete content:\n " << llsdxml.str() << llendl; + //LL_INFOS() << "upload complete content:\n " << llsdxml.str() << LL_ENDL; LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); @@ -456,57 +448,6 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) */ } -LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type, - LLBakedUploadData * baked_upload_data) : - LLAssetUploadResponder(post_data, vfile_id, asset_type), - mBakedUploadData(baked_upload_data) -{ -} - -LLSendTexLayerResponder::~LLSendTexLayerResponder() -{ - // mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below - if (mBakedUploadData) - { // ...but delete it in the case where uploadComplete() is never called - delete mBakedUploadData; - mBakedUploadData = NULL; - } -} - - -// Baked texture upload completed -void LLSendTexLayerResponder::uploadComplete(const LLSD& content) -{ - LLUUID item_id = mPostData["item_id"]; - - std::string result = content["state"]; - LLUUID new_id = content["new_asset"]; - - llinfos << "result: " << result << " new_id: " << new_id << llendl; - if (result == "complete" - && mBakedUploadData != NULL) - { // Invoke - LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE); - mBakedUploadData = NULL; // deleted in onTextureUploadComplete() - } - else - { // Invoke the original callback with an error result - LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); - mBakedUploadData = NULL; // deleted in onTextureUploadComplete() - } -} - -void LLSendTexLayerResponder::httpFailure(void) -{ - llinfos << "status: " << mStatus << " reason: " << mReason << llendl; - - // Invoke the original callback with an error result - LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); - mBakedUploadData = NULL; // deleted in onTextureUploadComplete() -} - LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, @@ -533,7 +474,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) if(!item) { llwarns << "Inventory item for " << mVFileID - << " is no longer in agent inventory." << llendl; + << " is no longer in agent inventory." << LL_ENDL; return; } @@ -544,7 +485,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) gInventory.notifyObservers(); llinfos << "Inventory item " << item->getName() << " saved into " - << content["new_asset"].asString() << llendl; + << content["new_asset"].asString() << LL_ENDL; LLInventoryType::EType inventory_type = new_item->getInventoryType(); switch(inventory_type) @@ -605,6 +546,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) { previewp->onUpdateSucceeded(); } + break; } case LLInventoryType::IT_WEARABLE: @@ -650,8 +592,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) case LLAssetType::AT_NOTECARD: { // Update the UI with the new asset. - LLPreviewNotecard* nc; - nc = (LLPreviewNotecard*)LLPreview::find(item_id); + LLPreviewNotecard* nc = (LLPreviewNotecard*)LLPreview::find(item_id); if (nc) { // *HACK: we have to delete the asset in the VFS so @@ -674,8 +615,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) { if (mQueueId.notNull()) { - LLFloaterCompileQueue* queue = - (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId); + LLFloaterCompileQueue* queue = (LLFloaterCompileQueue*) LLFloaterScriptQueue::findInstance(mQueueId); if (NULL != queue) { queue->removeItemByItemID(item_id); @@ -724,7 +664,7 @@ public: { llwarns << "LLAssetUploadResponder called with nonexistant " - << "vfile_id " << vfile_id << llendl; + << "vfile_id " << vfile_id << LL_ENDL; mVFileID.setNull(); mAssetType = LLAssetType::AT_NONE; } @@ -1020,17 +960,15 @@ LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResp delete mImpl; } -void LLNewAgentInventoryVariablePriceResponder::httpFailure(void) +void LLNewAgentInventoryVariablePriceResponder::httpFailure() { - lldebugs - << "LLNewAgentInventoryVariablePrice::error " << mStatus - << " reason: " << mReason << llendl; + const LLSD& content = getContent(); + LL_WARNS("Upload") << dumpResponse() << LL_ENDL; - if ( mContent.has("error") ) - { static const std::string _ERROR = "error"; - - mImpl->onTransportError(mContent[_ERROR]); + if ( content.has(_ERROR) ) + { + mImpl->onTransportError(content[_ERROR]); } else { @@ -1038,8 +976,14 @@ void LLNewAgentInventoryVariablePriceResponder::httpFailure(void) } } -void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) +void LLNewAgentInventoryVariablePriceResponder::httpSuccess() { + const LLSD& content = getContent(); + if (!content.isMap()) + { + failureResult(HTTP_INTERNAL_ERROR_OTHER, "Malformed response contents", content); + return; + } // Parse out application level errors and the appropriate // responses for them static const std::string _ERROR = "error"; @@ -1053,13 +997,14 @@ void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) static const std::string _RSVP = "rsvp"; // Check for application level errors - if (mContent.has(_ERROR)) + if ( content.has(_ERROR) ) { - onApplicationLevelError(mContent[_ERROR]); + LL_WARNS("Upload") << dumpResponse() << LL_ENDL; + onApplicationLevelError(content[_ERROR]); return; } - std::string state = mContent[_STATE]; + std::string state = content[_STATE]; LLAssetType::EType asset_type = mImpl->getAssetType(); if (_COMPLETE == state) @@ -1068,11 +1013,11 @@ void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) if (mImpl->getFilename().empty()) { // rename the file in the VFS to the actual asset id - // llinfos << "Changing uploaded asset UUID to " << mContent["new_asset"].asUUID() << llendl; + // LL_INFOS() << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << LL_ENDL; gVFS->renameFile( mImpl->getVFileID(), asset_type, - mContent["new_asset"].asUUID(), + content["new_asset"].asUUID(), asset_type); } @@ -1083,8 +1028,8 @@ void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) mImpl->getFolderID(), mImpl->getItemName(), mImpl->getItemDescription(), - mContent, - mContent[_UPLOAD_PRICE].asInteger()); + content, + content[_UPLOAD_PRICE].asInteger()); // TODO* Add bulk (serial) uploading or add // a super class of this that does so @@ -1092,12 +1037,13 @@ void LLNewAgentInventoryVariablePriceResponder::httpSuccess(void) else if ( _CONFIRM_UPLOAD == state ) { showConfirmationDialog( - mContent[_UPLOAD_PRICE].asInteger(), - mContent[_RESOURCE_COST].asInteger(), - mContent[_RSVP].asString()); + content[_UPLOAD_PRICE].asInteger(), + content[_RESOURCE_COST].asInteger(), + content[_RSVP].asString()); } else { + LL_WARNS("Upload") << dumpResponse() << LL_ENDL; onApplicationLevelError(""); } } @@ -1170,3 +1116,4 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog( } } + diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index 2c2b87152..21787786f 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -36,10 +36,6 @@ #include "llhttpclient.h" #include "llinventory.h" -class AIHTTPTimeoutPolicy; -extern AIHTTPTimeoutPolicy assetUploadResponder_timeout; -extern AIHTTPTimeoutPolicy newAgentInventoryVariablePriceResponder_timeout; - void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type, LLInventoryType::EType inventory_type, const std::string inventory_type_string, @@ -53,6 +49,8 @@ void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type, // via capabilities class LLAssetUploadResponder : public LLHTTPClient::ResponderWithResult { +protected: + LOG_CLASS(LLAssetUploadResponder); public: LLAssetUploadResponder(const LLSD& post_data, const LLUUID& vfile_id, @@ -61,10 +59,12 @@ public: const std::string& file_name, LLAssetType::EType asset_type); ~LLAssetUploadResponder(); - /*virtual*/ void httpFailure(void); - /*virtual*/ void httpSuccess(void); - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return assetUploadResponder_timeout; } +protected: + virtual void httpFailure(); + virtual void httpSuccess(); + +public: virtual void uploadUpload(const LLSD& content); virtual void uploadComplete(const LLSD& content); virtual void uploadFailure(const LLSD& content); @@ -76,25 +76,24 @@ protected: std::string mFileName; }; +// TODO*: Remove this once deprecated class LLNewAgentInventoryResponder : public LLAssetUploadResponder { - void (*mCallBack)(bool, void*); - void* mUserData; + LOG_CLASS(LLNewAgentInventoryResponder); public: LLNewAgentInventoryResponder( const LLSD& post_data, const LLUUID& vfile_id, - LLAssetType::EType asset_type, - void (*callback)(bool, void*) = NULL, - void* user_data = NULL); + LLAssetType::EType asset_type); LLNewAgentInventoryResponder( const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type); - /*virtual*/ void httpFailure(void); virtual void uploadComplete(const LLSD& content); virtual void uploadFailure(const LLSD& content); - /*virtual*/ char const* getName(void) const { return "LLNewAgentInventoryResponder"; } + /*virtual*/ char const* getName() const { return "LLNewAgentInventoryResponder"; } +protected: + virtual void httpFailure(); }; // A base class which goes through and performs some default @@ -104,6 +103,7 @@ public: class LLNewAgentInventoryVariablePriceResponder : public LLHTTPClient::ResponderWithResult { + LOG_CLASS(LLNewAgentInventoryVariablePriceResponder); public: LLNewAgentInventoryVariablePriceResponder( const LLUUID& vfile_id, @@ -116,10 +116,11 @@ public: const LLSD& inventory_info); virtual ~LLNewAgentInventoryVariablePriceResponder(); - /*virtual*/ void httpFailure(void); - /*virtual*/ void httpSuccess(void); - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return newAgentInventoryVariablePriceResponder_timeout; } +private: + /* virtual */ void httpFailure(); + /* virtual */ void httpSuccess(); +public: virtual void onApplicationLevelError( const LLSD& error); virtual void showConfirmationDialog( @@ -132,25 +133,6 @@ private: Impl* mImpl; }; -struct LLBakedUploadData; -class LLSendTexLayerResponder : public LLAssetUploadResponder -{ - LOG_CLASS(LLSendTexLayerResponder); -public: - LLSendTexLayerResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type, - LLBakedUploadData * baked_upload_data); - - ~LLSendTexLayerResponder(); - - /*virtual*/ void uploadComplete(const LLSD& content); - /*virtual*/ void httpFailure(void); - /*virtual*/ char const* getName(void) const { return "LLSendTexLayerResponder"; } - - LLBakedUploadData * mBakedUploadData; -}; - class LLUpdateAgentInventoryResponder : public LLAssetUploadResponder { public: @@ -161,7 +143,7 @@ public: const std::string& file_name, LLAssetType::EType asset_type); virtual void uploadComplete(const LLSD& content); - /*virtual*/ char const* getName(void) const { return "LLUpdateAgentInventoryResponder"; } + /*virtual*/ char const* getName() const { return "LLUpdateAgentInventoryResponder"; } }; class LLUpdateTaskInventoryResponder : public LLAssetUploadResponder @@ -179,7 +161,7 @@ public: LLAssetType::EType asset_type); virtual void uploadComplete(const LLSD& content); - /*virtual*/ char const* getName(void) const { return "LLUpdateTaskInventoryResponder"; } + /*virtual*/ char const* getName() const { return "LLUpdateTaskInventoryResponder"; } private: LLUUID mQueueId; diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index d798540e8..6b47c2680 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -68,7 +68,7 @@ extern U32 gFrameCount; namespace { - void chat_avatar_status(const std::string& name, const LLUUID& key, ERadarStatType type, bool entering) + void chat_avatar_status(const std::string& name, const LLUUID& key, ERadarStatType type, bool entering, const F32& dist) { if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) return; // RLVa:LF Don't announce people are around when blind, that cheats the system. static LLCachedControl radar_chat_alerts(gSavedSettings, "RadarChatAlerts"); @@ -96,6 +96,11 @@ namespace if (args.find("[RANGE]") != args.end()) chat.mText = self->getString("template", args); else if (chat.mText.empty()) return; + if (entering) // Note: If we decide to make this for leaving as well, change this check to dist != F32_MIN + { + static const LLCachedControl radar_show_dist("RadarAlertShowDist"); + if (radar_show_dist) chat.mText += llformat(" (%.2fm)", dist); + } chat.mFromName = name; chat.mURL = llformat("secondlife:///app/agent/%s/about",key.asString().c_str()); chat.mSourceType = CHAT_SOURCE_SYSTEM; @@ -160,7 +165,7 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); if ((U32)mAge < sAvatarAgeAlertDays) { - chat_avatar_status(mName, mID, STAT_TYPE_AGE, mStats[STAT_TYPE_AGE] = true); + chat_avatar_status(mName, mID, STAT_TYPE_AGE, mStats[STAT_TYPE_AGE] = true, (mPosition - gAgent.getPositionGlobal()).magVec()); } } // If one wanted more information that gets displayed on profiles to be displayed, here would be the place to do it. @@ -168,14 +173,18 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) } } -void LLAvatarListEntry::setPosition(const LLVector3d& position, bool this_sim, bool drawn, bool chatrange, bool shoutrange) +void LLAvatarListEntry::setPosition(const LLVector3d& position, const F32& dist, bool drawn) { mPosition = position; mFrame = gFrameCount; - if (this_sim != mStats[STAT_TYPE_SIM]) chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim); - if (drawn != mStats[STAT_TYPE_DRAW]) chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn); - if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange); - if (chatrange != mStats[STAT_TYPE_CHATRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange); + bool here(dist != F32_MIN); // F32_MIN only if dead + bool this_sim(here && (gAgent.getRegion()->pointInRegionGlobal(position) || !(LLWorld::getInstance()->positionRegionValidGlobal(position)))); + if (this_sim != mStats[STAT_TYPE_SIM]) chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim, dist); + if (drawn != mStats[STAT_TYPE_DRAW]) chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn, dist); + bool shoutrange(here && dist < LFSimFeatureHandler::getInstance()->shoutRange()); + if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange, dist); + bool chatrange(here && dist < LFSimFeatureHandler::getInstance()->sayRange()); + if (chatrange != mStats[STAT_TYPE_CHATRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange, dist); mUpdateTimer.start(); } @@ -553,8 +562,7 @@ void LLFloaterAvatarList::updateAvatarList() } // Announce position - F32 dist((position - mypos).magVec()); - entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position) || !(LLWorld::getInstance()->positionRegionValidGlobal(position)), avatarp, dist < LFSimFeatureHandler::getInstance()->sayRange(), dist < LFSimFeatureHandler::getInstance()->shoutRange()); + entry->setPosition(position, (position - mypos).magVec(), avatarp); // Mark as typing if they are typing if (avatarp && avatarp->isTyping()) entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING); @@ -621,7 +629,7 @@ void LLFloaterAvatarList::expireAvatarList() } else { - entry->setPosition(entry->getPosition(), false, false, false, false); // Dead and gone + entry->setPosition(entry->getPosition(), F32_MIN, false); // Dead and gone it = mAvatars.erase(it); } } @@ -700,151 +708,171 @@ void LLFloaterAvatarList::refreshAvatarList() LLScrollListItem::Params element; element.value = av_id; - LLScrollListCell::Params mark; - mark.column = "marked"; - mark.type = "text"; - if (entry->isMarked()) + static const LLCachedControl hide_mark("RadarColumnMarkHidden"); + if (!hide_mark) { - mark.value = "X"; - mark.color = LLColor4::blue; - mark.font_style = "BOLD"; - } - - LLScrollListCell::Params name; - name.column = "avatar_name"; - name.type = "text"; - name.value = entry->getName(); - if (entry->isFocused()) - { - name.font_style = "BOLD"; - } - - // custom colors for certain types of avatars! - //Changed a bit so people can modify them in settings. And since they're colors, again it's possibly account-based. Starting to think I need a function just to determine that. - HgB - //name.color = gColors.getColor( "MapAvatar" ); - LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry->getPosition()); - LLUUID estate_owner = LLUUID::null; - if (parent_estate && parent_estate->isAlive()) - { - estate_owner = parent_estate->getOwner(); + LLScrollListCell::Params mark; + mark.column = "marked"; + mark.type = "text"; + if (entry->isMarked()) + { + mark.value = "X"; + mark.color = LLColor4::blue; + mark.font_style = "BOLD"; + } + element.columns.add(mark); } static const LLCachedControl unselected_color(gColors, "ScrollUnselectedColor", LLColor4(0.f, 0.f, 0.f, 0.8f)); - static LLCachedControl sDefaultListText(gColors, "DefaultListText"); - static LLCachedControl sRadarTextChatRange(gColors, "RadarTextChatRange"); - static LLCachedControl sRadarTextShoutRange(gColors, "RadarTextShoutRange"); - static LLCachedControl sRadarTextDrawDist(gColors, "RadarTextDrawDist"); - static LLCachedControl sRadarTextYoung(gColors, "RadarTextYoung"); + static const LLCachedControl sDefaultListText(gColors, "DefaultListText"); static const LLCachedControl ascent_muted_color("AscentMutedColor", LLColor4(0.7f,0.7f,0.7f,1.f)); LLColor4 color = sDefaultListText; - //Lindens are always more Linden than your friend, make that take precedence - if (mm_getMarkerColor(av_id, color)) {} - else if (LLMuteList::getInstance()->isLinden(av_id)) + // Name never hidden { - static const LLCachedControl ascent_linden_color("AscentLindenColor", LLColor4(0.f,0.f,1.f,1.f)); - color = ascent_linden_color; + LLScrollListCell::Params name; + name.column = "avatar_name"; + name.type = "text"; + name.value = entry->getName(); + if (entry->isFocused()) + { + name.font_style = "BOLD"; + } + + // custom colors for certain types of avatars! + //Changed a bit so people can modify them in settings. And since they're colors, again it's possibly account-based. Starting to think I need a function just to determine that. - HgB + //name.color = gColors.getColor( "MapAvatar" ); + LLUUID estate_owner = LLUUID::null; + if (LLViewerRegion* parent_estate = LLWorld::getInstance()->getRegionFromPosGlobal(entry->getPosition())) + if (parent_estate->isAlive()) + estate_owner = parent_estate->getOwner(); + + //Lindens are always more Linden than your friend, make that take precedence + if (mm_getMarkerColor(av_id, color)) {} + else if (LLMuteList::getInstance()->isLinden(av_id)) + { + static const LLCachedControl ascent_linden_color("AscentLindenColor", LLColor4(0.f,0.f,1.f,1.f)); + color = ascent_linden_color; + } + //check if they are an estate owner at their current position + else if (estate_owner.notNull() && av_id == estate_owner) + { + static const LLCachedControl ascent_estate_owner_color("AscentEstateOwnerColor", LLColor4(1.f,0.6f,1.f,1.f)); + color = ascent_estate_owner_color; + } + //without these dots, SL would suck. + else if (LLAvatarActions::isFriend(av_id)) + { + static const LLCachedControl ascent_friend_color("AscentFriendColor", LLColor4(1.f,1.f,0.f,1.f)); + color = ascent_friend_color; + } + //big fat jerkface who is probably a jerk, display them as such. + else if (LLMuteList::getInstance()->isMuted(av_id)) + { + color = ascent_muted_color; + } + name.color = color*0.5f + unselected_color*0.5f; + element.columns.add(name); } - //check if they are an estate owner at their current position - else if (estate_owner.notNull() && av_id == estate_owner) - { - static const LLCachedControl ascent_estate_owner_color("AscentEstateOwnerColor", LLColor4(1.f,0.6f,1.f,1.f)); - color = ascent_estate_owner_color; - } - //without these dots, SL would suck. - else if (LLAvatarActions::isFriend(av_id)) - { - static const LLCachedControl ascent_friend_color("AscentFriendColor", LLColor4(1.f,1.f,0.f,1.f)); - color = ascent_friend_color; - } - //big fat jerkface who is probably a jerk, display them as such. - else if (LLMuteList::getInstance()->isMuted(av_id)) - { - color = ascent_muted_color; - } - name.color = color*0.5f + unselected_color*0.5f; char temp[32]; - color = sDefaultListText; - LLScrollListCell::Params dist; - dist.column = "distance"; - dist.type = "text"; - if (UnknownAltitude) + // Distance never hidden { - strcpy(temp, "?"); - if (entry->mStats[STAT_TYPE_DRAW]) + color = sDefaultListText; + LLScrollListCell::Params dist; + dist.column = "distance"; + dist.type = "text"; + static const LLCachedControl sRadarTextDrawDist(gColors, "RadarTextDrawDist"); + if (UnknownAltitude) { - color = sRadarTextDrawDist; - } - } - else - { - if (distance <= LFSimFeatureHandler::getInstance()->shoutRange()) - { - snprintf(temp, sizeof(temp), "%.1f", distance); - color = (distance > LFSimFeatureHandler::getInstance()->sayRange()) ? sRadarTextShoutRange : sRadarTextChatRange; + strcpy(temp, "?"); + if (entry->mStats[STAT_TYPE_DRAW]) + { + color = sRadarTextDrawDist; + } } else { - if (entry->mStats[STAT_TYPE_DRAW]) color = sRadarTextDrawDist; - snprintf(temp, sizeof(temp), "%d", (S32)distance); + if (distance <= LFSimFeatureHandler::getInstance()->shoutRange()) + { + static const LLCachedControl sRadarTextChatRange(gColors, "RadarTextChatRange"); + static const LLCachedControl sRadarTextShoutRange(gColors, "RadarTextShoutRange"); + snprintf(temp, sizeof(temp), "%.1f", distance); + color = (distance > LFSimFeatureHandler::getInstance()->sayRange()) ? sRadarTextShoutRange : sRadarTextChatRange; + } + else + { + if (entry->mStats[STAT_TYPE_DRAW]) color = sRadarTextDrawDist; + snprintf(temp, sizeof(temp), "%d", (S32)distance); + } } + dist.value = temp; + dist.color = color * 0.7f + unselected_color * 0.3f; // Liru: Blend testing! + //dist.color = color; + element.columns.add(dist); } - dist.value = temp; - dist.color = color * 0.7f + unselected_color * 0.3f; // Liru: Blend testing! - //dist.color = color; - LLScrollListCell::Params pos; - position -= simpos; + static const LLCachedControl hide_pos("RadarColumnPositionHidden"); + if (!hide_pos) + { + LLScrollListCell::Params pos; + position -= simpos; - S32 x(position.mdV[VX]); - S32 y(position.mdV[VY]); - if (x >= 0 && x <= width && y >= 0 && y <= width) - { - snprintf(temp, sizeof(temp), "%d, %d", x, y); + S32 x(position.mdV[VX]); + S32 y(position.mdV[VY]); + if (x >= 0 && x <= width && y >= 0 && y <= width) + { + snprintf(temp, sizeof(temp), "%d, %d", x, y); + } + else + { + temp[0] = '\0'; + if (y < 0) + { + strcat(temp, "S"); + } + else if (y > width) + { + strcat(temp, "N"); + } + if (x < 0) + { + strcat(temp, "W"); + } + else if (x > width) + { + strcat(temp, "E"); + } + } + pos.column = "position"; + pos.type = "text"; + pos.value = temp; + element.columns.add(pos); } - else - { - temp[0] = '\0'; - if (y < 0) - { - strcat(temp, "S"); - } - else if (y > width) - { - strcat(temp, "N"); - } - if (x < 0) - { - strcat(temp, "W"); - } - else if (x > width) - { - strcat(temp, "E"); - } - } - pos.column = "position"; - pos.type = "text"; - pos.value = temp; - LLScrollListCell::Params alt; - alt.column = "altitude"; - alt.type = "text"; - if (UnknownAltitude) + static const LLCachedControl hide_alt("RadarColumnAltitudeHidden"); + if (!hide_alt) { - strcpy(temp, "?"); + LLScrollListCell::Params alt; + alt.column = "altitude"; + alt.type = "text"; + if (UnknownAltitude) + { + strcpy(temp, "?"); + } + else + { + snprintf(temp, sizeof(temp), "%d", (S32)position.mdV[VZ]); + } + alt.value = temp; + element.columns.add(alt); } - else - { - snprintf(temp, sizeof(temp), "%d", (S32)position.mdV[VZ]); - } - alt.value = temp; - LLScrollListCell::Params act; static const LLCachedControl hide_act("RadarColumnActivityHidden"); if (!hide_act) { + LLScrollListCell::Params act; act.column = "activity"; act.type = "icon"; switch(entry->getActivity()) @@ -880,12 +908,13 @@ void LLFloaterAvatarList::refreshAvatarList() default: break; } + element.columns.add(act); } - LLScrollListCell::Params voice; static const LLCachedControl hide_voice("RadarColumnVoiceHidden"); if (!hide_voice) { + LLScrollListCell::Params voice; voice.column("voice"); voice.type("icon"); // transplant from llparticipantlist.cpp, update accordingly. @@ -914,71 +943,78 @@ void LLFloaterAvatarList::refreshAvatarList() voice.color(speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE ? LLColor4::transparent : speakerp->mDotColor); } } + element.columns.add(voice); } - LLScrollListCell::Params agep; - agep.column = "age"; - agep.type = "text"; - color = sDefaultListText; - std::string age = boost::lexical_cast(entry->mAge); - if (entry->mAge > -1) + static const LLCachedControl hide_age("RadarColumnAgeHidden"); + if (!hide_age) { - static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); - if ((U32)entry->mAge < sAvatarAgeAlertDays) - color = sRadarTextYoung; - } - else - { - age = "?"; - } - agep.value = age; - agep.color = color; - - int dur = difftime(time(NULL), entry->getTime()); - int hours = dur / 3600; - int mins = (dur % 3600) / 60; - int secs = (dur % 3600) % 60; - - LLScrollListCell::Params time; - time.column = "time"; - time.type = "text"; - time.value = llformat("%d:%02d:%02d", hours, mins, secs); - - LLScrollListCell::Params viewer; - viewer.column = "client"; - viewer.type = "text"; - - static const LLCachedControl avatar_name_color(gColors, "AvatarNameColor",LLColor4(0.98f, 0.69f, 0.36f, 1.f)); - color = avatar_name_color; - if (LLVOAvatar* avatarp = gObjectList.findAvatar(av_id)) - { - std::string client = SHClientTagMgr::instance().getClientName(avatarp, false); - if (client.empty()) + LLScrollListCell::Params agep; + agep.column = "age"; + agep.type = "text"; + color = sDefaultListText; + std::string age = boost::lexical_cast(entry->mAge); + if (entry->mAge > -1) { - color = unselected_color; - client = "?"; + static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); + if ((U32)entry->mAge < sAvatarAgeAlertDays) + { + static const LLCachedControl sRadarTextYoung(gColors, "RadarTextYoung"); + color = sRadarTextYoung; + } } - else SHClientTagMgr::instance().getClientColor(avatarp, false, color); - viewer.value = client.c_str(); + else + { + age = "?"; + } + agep.value = age; + agep.color = color; + element.columns.add(agep); } - else - { - viewer.value = getString("Out Of Range"); - } - //Blend to make the color show up better - viewer.color = color *.5f + unselected_color * .5f; - // Add individual column cell params to the item param - element.columns.add(mark); - element.columns.add(name); - element.columns.add(dist); - element.columns.add(pos); - element.columns.add(alt); - if (!hide_act) element.columns.add(act); - if (!hide_voice) element.columns.add(voice); - element.columns.add(agep); - element.columns.add(time); - element.columns.add(viewer); + static const LLCachedControl hide_time("RadarColumnTimeHidden"); + if (!hide_time) + { + int dur = difftime(time(NULL), entry->getTime()); + int hours = dur / 3600; + int mins = (dur % 3600) / 60; + int secs = (dur % 3600) % 60; + + LLScrollListCell::Params time; + time.column = "time"; + time.type = "text"; + time.value = llformat("%d:%02d:%02d", hours, mins, secs); + element.columns.add(time); + } + + static const LLCachedControl hide_client("RadarColumnClientHidden"); + if (!hide_client) + { + LLScrollListCell::Params viewer; + viewer.column = "client"; + viewer.type = "text"; + + static const LLCachedControl avatar_name_color(gColors, "AvatarNameColor",LLColor4(0.98f, 0.69f, 0.36f, 1.f)); + color = avatar_name_color; + if (LLVOAvatar* avatarp = gObjectList.findAvatar(av_id)) + { + std::string client = SHClientTagMgr::instance().getClientName(avatarp, false); + if (client.empty()) + { + color = unselected_color; + client = "?"; + } + else SHClientTagMgr::instance().getClientColor(avatarp, false, color); + viewer.value = client.c_str(); + } + else + { + viewer.value = getString("Out Of Range"); + } + //Blend to make the color show up better + viewer.color = color *.5f + unselected_color * .5f; + element.columns.add(viewer); + } // Add to list mAvatarList->addRow(element); diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 222107c12..d77231509 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -80,7 +80,7 @@ enum ACTIVITY_TYPE * Update world position. * Affects age. */ - void setPosition(const LLVector3d& position, bool this_sim, bool drawn, bool chatrange, bool shoutrange); + void setPosition(const LLVector3d& position, const F32& dist, bool drawn); const LLVector3d& getPosition() const { return mPosition; } diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 9d7e2c0be..29019118c 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -1426,7 +1426,7 @@ void LLSnapshotLivePreview::saveTexture() LLAssetStorage::LLStoreAssetCallback callback = &LLSnapshotLivePreview::saveTextureDone; S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); saveTextureUserData* user_data = new saveTextureUserData(this, sSnapshotIndex, gSavedSettings.getBOOL("TemporaryUpload")); - if (!upload_new_resource(tid, // tid + if (upload_new_resource(tid, // tid LLAssetType::AT_TEXTURE, "Snapshot : " + pos_string, "Taken by " + who_took_it + " at " + pos_string, @@ -1437,7 +1437,11 @@ void LLSnapshotLivePreview::saveTexture() LLFloaterPerms::getGroupPerms("Uploads"), // that is more permissive than other uploads LLFloaterPerms::getEveryonePerms("Uploads"), "Snapshot : " + pos_string, - callback, expected_upload_cost, user_data, &LLSnapshotLivePreview::saveTextureDone2)) + callback, expected_upload_cost, user_data)) + { + saveTextureDone2(true, user_data); + } + else { // Something went wrong. delete user_data; diff --git a/indra/newview/llmediafilter.cpp b/indra/newview/llmediafilter.cpp index 56d01e422..528dfc86f 100644 --- a/indra/newview/llmediafilter.cpp +++ b/indra/newview/llmediafilter.cpp @@ -101,7 +101,6 @@ void LLMediaFilter::filterAudioUrl(const std::string& url) { if (url.empty()) { - gAudiop->startInternetStream(url); return; } if (url == mCurrentAudioURL) return; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index c10570d7d..55f723651 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5201,7 +5201,9 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data { if (node->mInventorySerial != inv_serial) { - node->getObject()->dirtyInventory(); + if (LLViewerObject* object = node->getObject()) + if (object->getInventorySerial() != inv_serial) // Singu Note: the serial number in the object may be correct. + object->dirtyInventory(); } // save texture data as soon as we get texture perms first time diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 301a461f7..c6e2fdc86 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -1177,8 +1177,7 @@ bool upload_new_resource( const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, - void *userdata, - void (*callback2)(bool, void*)) + void *userdata) { if(gDisconnected) { @@ -1230,9 +1229,7 @@ bool upload_new_resource( new LLNewAgentInventoryResponder( body, uuid, - asset_type, - callback2, - userdata)); + asset_type)); } else { @@ -1294,17 +1291,16 @@ bool upload_new_resource( LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid) { - LLAssetID uuid; - if (gDisconnected) { - uuid.setNull(); - } - else - { - uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + LLAssetID rv; + + rv.setNull(); + return rv; } + LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + return uuid; } diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 65ff1a425..4eefa6a93 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -78,8 +78,7 @@ bool upload_new_resource(const LLTransactionID &tid, const std::string& display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, - void *userdata, - void (*callback2)(bool, void*) = NULL); + void *userdata); // The default callback functions, called when 'callback' == NULL (for normal and temporary uploads). // user_data must be a LLResourceData allocated with new (or NULL). diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index a24a8b231..e8072a5cf 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -29,76 +29,60 @@ #include "llviewerprecompiledheaders.h" -// system library includes #include #include #include -// linden library includes -#include "indra_constants.h" -#include "llapr.h" #include "llcallbacklist.h" #include "lldir.h" #include "lleconomy.h" #include "llhttpclient.h" -#include "llimage.h" +#include "llinventorydefines.h" #include "llimagej2c.h" #include "lllfsthread.h" #include "llnotificationsutil.h" #include "llsdserialize.h" -#include "llsdutil.h" #include "llsdutil_math.h" #include "lltransactiontypes.h" -#include "llinventorydefines.h" +#include "lluictrlfactory.h" +#include "lluploaddialog.h" -// newview includes #include "llagent.h" #include "llappviewer.h" #include "llassetuploadresponders.h" -#include "statemachine/aifilepicker.h" -#include "llfloaterbvhpreview.h" -#include "llfloaterbuycurrency.h" -#include "llfloaterimagepreview.h" -#include "llfloaternamedesc.h" -#include "llfloatersnapshot.h" -#include "llinventorymodel.h" // gInventory #include "llinventoryfunctions.h" -#include "llresourcedata.h" +#include "llinventorymodel.h" // for gInventory #include "llmaterialmgr.h" #include "llselectmgr.h" -#include "llstatusbar.h" #include "lltexturecache.h" #include "lltoolplacer.h" -#include "lluictrlfactory.h" -#include "lluploaddialog.h" #include "llviewercontrol.h" #include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewermenu.h" +#include "lfsimfeaturehandler.h" #include "llviewerregion.h" -#include "llviewerstats.h" #include "llviewerwindow.h" -#include "hippogridmanager.h" -#include "lfsimfeaturehandler.h" - -#include "llviewerobjectbackup.h" - -LLObjectBackup* LLObjectBackup::sInstance = NULL; +#include "llviewerobjectbackup.h" // Note: these default textures are initialized with hard coded values to // prevent cheating. When not in SL, the user-configurable values are used // instead (see setDefaultTextures() below). -static LLUUID LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f"); -static LLUUID LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f"); -static LLUUID LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837"); -static LLUUID LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); -static LLUUID LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"); +LLUUID LL_TEXTURE_PLYWOOD = LLUUID("89556747-24cb-43ed-920b-47caed15465f"); +LLUUID LL_TEXTURE_BLANK = LLUUID("5748decc-f629-461c-9a36-a35a221fe21f"); +LLUUID LL_TEXTURE_INVISIBLE = LLUUID("38b86f85-2575-52a9-a531-23108d8da837"); +LLUUID LL_TEXTURE_TRANSPARENT = LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); +LLUUID LL_TEXTURE_MEDIA = LLUUID("8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"); -class importResponder : public LLNewAgentInventoryResponder +class ImportObjectResponder: public LLNewAgentInventoryResponder { +protected: + LOG_CLASS(ImportObjectResponder); + public: - importResponder(const LLSD& post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type) + ImportObjectResponder(const LLSD& post_data, const LLUUID& vfile_id, + LLAssetType::EType asset_type) : LLNewAgentInventoryResponder(post_data, vfile_id, asset_type) { } @@ -106,10 +90,18 @@ public: //virtual virtual void uploadComplete(const LLSD& content) { - LL_DEBUGS("ObjectBackup") << "LLNewAgentInventoryResponder::result from capabilities" << LL_ENDL; + LLObjectBackup* self = LLObjectBackup::findInstance(); + if (!self) + { + llwarns << "Import aborted, LLObjectBackup instance gone !" + << llendl; + // remove the "Uploading..." message + LLUploadDialog::modalUploadFinished(); + return; + } LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); - LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); + LLInventoryType::EType inv_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); // Update L$ and ownership credit information // since it probably changed on the server @@ -117,18 +109,19 @@ public: asset_type == LLAssetType::AT_SOUND || asset_type == LLAssetType::AT_ANIMATION) { - gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); - gMessageSystem->nextBlockFast(_PREHASH_MoneyData); - gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MoneyBalanceRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); + msg->nextBlockFast(_PREHASH_MoneyData); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); gAgent.sendReliableMessage(); } // Actually add the upload to viewer inventory - LL_INFOS("ObjectBackup") << "Adding " << content["new_inventory_item"].asUUID() << " " - << content["new_asset"].asUUID() << " to inventory." << LL_ENDL; + llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " + << content["new_asset"].asUUID() << " to inventory." << llendl; if (mPostData["folder_id"].asUUID().notNull()) { LLPermissions perm; @@ -144,13 +137,12 @@ public: } perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); S32 creation_date_now = time_corrected(); - LLPointer item - = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), + LLPointer item; + item = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), mPostData["folder_id"].asUUID(), perm, content["new_asset"].asUUID(), - asset_type, - inventory_type, + asset_type, inv_type, mPostData["name"].asString(), mPostData["description"].asString(), LLSaleInfo::DEFAULT, @@ -161,35 +153,43 @@ public: } else { - LL_WARNS("ObjectBackup") << "Can't find a folder to put it into" << LL_ENDL; + llwarns << "Can't find a folder to put it into" << llendl; } // remove the "Uploading..." message LLUploadDialog::modalUploadFinished(); - LLObjectBackup::getInstance()->updateMap(content["new_asset"].asUUID()); - LLObjectBackup::getInstance()->uploadNextAsset(); + self->updateMap(content["new_asset"].asUUID()); + self->uploadNextAsset(); } /*virtual*/ char const* getName(void) const { return "importResponder"; } }; -class CacheReadResponder : public LLTextureCache::ReadResponder +class BackupCacheReadResponder : public LLTextureCache::ReadResponder { +protected: + LOG_CLASS(BackupCacheReadResponder); + public: - CacheReadResponder(const LLUUID& id, LLImageFormatted* image) + BackupCacheReadResponder(const LLUUID& id, LLImageFormatted* image) : mFormattedImage(image), mID(id) { setImage(image); } - void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) + void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, + BOOL imagelocal) { + LLObjectBackup* self = LLObjectBackup::findInstance(); + if (!self) return; + if (imageformat == IMG_CODEC_TGA && mFormattedImage->getCodec() == IMG_CODEC_J2C) { - LL_WARNS("ObjectBackup") << "FAILED: texture " << mID << " is formatted as TGA. Not saving." << LL_ENDL; - LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_BAD_ENCODING; + llwarns << "FAILED: texture " << mID + << " is formatted as TGA. Not saving." << llendl; + self->mNonExportedTextures |= LLObjectBackup::TEXTURE_BAD_ENCODING; mFormattedImage = NULL; mImageSize = 0; return; @@ -197,8 +197,20 @@ public: if (mFormattedImage.notNull()) { - llassert_always(mFormattedImage->getCodec() == imageformat); - mFormattedImage->appendData(data, datasize); + if (mFormattedImage->getCodec() == imageformat) + { + mFormattedImage->appendData(data, datasize); + } + else + { + llwarns << "FAILED: texture " << mID + << " is formatted as " << mFormattedImage->getCodec() + << " while expecting " << imageformat + << ". Not saving." << llendl; + mFormattedImage = NULL; + mImageSize = 0; + return; + } } else { @@ -211,34 +223,42 @@ public: virtual void completed(bool success) { + LLObjectBackup* self = LLObjectBackup::findInstance(); + if (!self) + { + llwarns << "Export aborted, LLObjectBackup instance gone !" + << llendl; + return; + } + if (success && mFormattedImage.notNull() && mImageSize > 0) { - LL_INFOS("ObjectBackup") << "SUCCESS getting texture " << mID << LL_ENDL; + llinfos << "SUCCESS getting texture " << mID << llendl; std::string name; mID.toString(name); - name = LLObjectBackup::getInstance()->getfolder() + "//" + name; - LL_INFOS("ObjectBackup") << "Saving to " << name << LL_ENDL; + name = self->getFolder() + "//" + name; + llinfos << "Saving to " << name << llendl; if (!mFormattedImage->save(name)) { - LL_WARNS("ObjectBackup") << "FAILED to save texture " << mID << LL_ENDL; - LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_SAVED_FAILED; + llwarns << "FAILED to save texture " << mID << llendl; + self->mNonExportedTextures |= LLObjectBackup::TEXTURE_SAVED_FAILED; } } else { if (!success) { - LL_WARNS("ObjectBackup") << "FAILED to get texture " << mID << LL_ENDL; - LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_MISSING; + llwarns << "FAILED to get texture " << mID << llendl; + self->mNonExportedTextures |= LLObjectBackup::TEXTURE_MISSING; } if (mFormattedImage.isNull()) { - LL_WARNS("ObjectBackup") << "FAILED: NULL texture " << mID << LL_ENDL; - LLObjectBackup::getInstance()->mNonExportedTextures |= LLObjectBackup::TEXTURE_IS_NULL; + llwarns << "FAILED: NULL texture " << mID << llendl; + self->mNonExportedTextures |= LLObjectBackup::TEXTURE_IS_NULL; } } - LLObjectBackup::getInstance()->mCheckNextTexture = true; + self->mCheckNextTexture = true; } private: @@ -246,62 +266,70 @@ private: LLUUID mID; }; -LLObjectBackup::LLObjectBackup() -: LLFloater(std::string("Object Backup Floater"), std::string("FloaterObjectBackuptRect"), LLStringUtil::null) +LLObjectBackup::LLObjectBackup(const LLSD&) +: mRunning(false), + mRetexture(false), + mTexturesList(), + mAssetMap(), + mCurrentAsset() { //buildFromFile("floater_object.xml"); - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_object_backup.xml", NULL, false); - mRunning = false; - mTexturesList.clear(); - mAssetMap.clear(); - mCurrentAsset.setNull(); - mRetexture = false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLObjectBackup* LLObjectBackup::getInstance() -{ - if (!sInstance) - { - sInstance = new LLObjectBackup(); - } - return sInstance; + LLUICtrlFactory::getInstance()->buildFloater(this, + "floater_object_backup.xml", + NULL, false); // Don't open } +//virtual LLObjectBackup::~LLObjectBackup() { - // save position of floater - gSavedSettings.setRect("FloaterObjectBackuptRect", getRect()); - sInstance = NULL; + // Just in case we got closed unexpectedly... + if (gIdleCallbacks.containsFunction(exportWorker)) + { + gIdleCallbacks.deleteFunction(exportWorker); + } } -void LLObjectBackup::show(bool exporting) +//static +bool LLObjectBackup::confirmCloseCallback(const LLSD& notification, + const LLSD& response) { - // set the title - if (exporting) + if (LLNotification::getSelectedOption(notification, response) == 0) { - setTitle("Object export"); + LLObjectBackup* self = findInstance(); + if (self) + { + self->destroy(); + } + } + return false; +} + +//virtual +void LLObjectBackup::onClose(bool app_quitting) +{ + // Do not destroy the floater on user close action to avoid getting things + // messed up during import/export. + if (app_quitting) + { + destroy(); } else { - setTitle("Object import"); + LLNotificationsUtil::add("ConfirmAbortBackup", LLSD(), LLSD(), + confirmCloseCallback); } - mCurObject = 1; - mCurPrim = 0; - mObjects = 0; - mPrims = 0; - mRezCount = 0; - - // make floater appear - setVisibleAndFrontmost(); } -void LLObjectBackup::onClose(bool app_quitting) +void LLObjectBackup::showFloater(bool exporting) { - setVisible(false); - // HACK for fast XML iteration replace with: - // destroy(); + // Set the title + setTitle(getString(exporting ? "export" : "import")); + + mCurObject = 1; + mCurPrim = mObjects = mPrims = mRezCount = 0; + + // Make the floater pop up + setVisibleAndFrontmost(); } void LLObjectBackup::updateExportNumbers() @@ -322,7 +350,8 @@ void LLObjectBackup::updateImportNumbers() if (mRetexture) { - sstr << " Textures uploads remaining : " << mTexturesList.size() << "\n"; + sstr << " Textures uploads remaining : " << mTexturesList.size() + << "\n"; ctrl->setValue(LLSD("Text") = sstr.str()); } else @@ -392,6 +421,7 @@ void LLObjectBackup::setDefaultTextures() } } +//static bool LLObjectBackup::validatePerms(const LLPermissions* item_permissions) { return item_permissions->allowExportBy(gAgentID, LFSimFeatureHandler::instance().exportPolicy()); @@ -406,18 +436,16 @@ bool LLObjectBackup::validatePerms(const LLPermissions* item_permissions) // The "must be creator" stuff also goes against the usage in Linden Lab's own // official viewers, since those allow you to save full perm textures (such as // the textures in the Library), whoever is the actual creator... Go figure ! -LLUUID LLObjectBackup::validateTextureID(const LLUUID& asset_id) -{ - if (!gHippoGridManager->getConnectedGrid()->isSecondLife()) - { - // If we are not in Second Life, don't bother. - return asset_id; - } - if (mBadPermsTexturesList.count(asset_id)) +//static +bool LLObjectBackup::validateTexturePerms(const LLUUID& asset_id) +{ + if (LFSimFeatureHandler::instance().exportPolicy() == ep_full_perm) { - // We already checked it and know it's bad... - return LL_TEXTURE_PLYWOOD; + // If we are not in Second Life and we don't have export-permission + // support, don't bother and unconditionally accept the texture export + // (legacy behaviour). + return true; } if (asset_id == LL_TEXTURE_PLYWOOD || @@ -427,7 +455,7 @@ LLUUID LLObjectBackup::validateTextureID(const LLUUID& asset_id) asset_id == LL_TEXTURE_MEDIA) { // Allow to export a few default SL textures. - return asset_id; + return true; } LLViewerInventoryCategory::cat_array_t cats; @@ -444,32 +472,94 @@ LLUUID LLObjectBackup::validateTextureID(const LLUUID& asset_id) const LLPermissions item_permissions = items[i]->getPermissions(); if (validatePerms(&item_permissions)) { - return asset_id; + return true; } } } + return false; +} + +LLUUID LLObjectBackup::validateTextureID(const LLUUID& asset_id) +{ + if (mBadPermsTexturesList.count(asset_id)) + { + // We already checked it and know it's bad... + return LL_TEXTURE_PLYWOOD; + } + else if (asset_id.isNull() || validateTexturePerms(asset_id)) + { + return asset_id; + } + else { mBadPermsTexturesList.insert(asset_id); // Cache bad texture ID mNonExportedTextures |= TEXTURE_BAD_PERM; - LL_WARNS("ObjectBackup") << "Bad permissions for texture ID: " << asset_id - << " - Texture will not be exported." << LL_ENDL; + llwarns << "Bad permissions for texture ID: " << asset_id + << " - Texture will not be exported." << llendl; return LL_TEXTURE_PLYWOOD; } } +//static +bool LLObjectBackup::validateNode(LLSelectNode* node) +{ + LLPermissions* perms = node->mPermissions; + if (!perms || !validatePerms(perms)) + { + return false; + } + + // Additionally check if this is a sculpt or a mesh object and if yes, if + // we have export permission on the sclupt texture or the mesh object. + LLViewerObject* obj = node->getObject(); + if (!obj) // Paranoia + { + return false; + } + else if (obj->isSculpted()) + { + if (obj->isMesh()) + { + return false; // We can't export mesh from here, anyway. + } + else + { + LLSculptParams* params; + params = (LLSculptParams*)obj->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLUUID sculpt_id = params->getSculptTexture(); + return validateTexturePerms(sculpt_id); + } + } + else + { + return true; + } +} //---------------------------------------------------------------------------// +//static void LLObjectBackup::exportWorker(void *userdata) { - getInstance()->updateExportNumbers(); + LLObjectBackup* self = findInstance(); + if (!self) + { + gIdleCallbacks.deleteFunction(exportWorker); + llwarns << "Export process aborted. LLObjectBackup instance gone !" + << llendl; + LLNotifications::instance().add("ExportAborted"); + return; + } - switch (getInstance()->mExportState) + self->updateExportNumbers(); + + switch (self->mExportState) { case EXPORT_INIT: { - getInstance()->show(true); + self->showFloater(true); + //LLSelectMgr::getInstance()->getSelection()->ref(); // Singu Note: Don't do this. // Fall through to EXPORT_CHECK_PERMS } case EXPORT_CHECK_PERMS: @@ -478,16 +568,17 @@ void LLObjectBackup::exportWorker(void *userdata) { virtual bool apply(LLSelectNode* node) { - return getInstance()->validatePerms(node->mPermissions); + return LLObjectBackup::validateNode(node); } } func; - LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + LLViewerObject* object; + object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); if (object) { if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) { - getInstance()->mExportState = EXPORT_FETCH_PHYSICS; + self->mExportState = EXPORT_FETCH_PHYSICS; } else { @@ -501,21 +592,21 @@ void LLObjectBackup::exportWorker(void *userdata) if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func2, false)) { - LL_WARNS("ObjectBackup") << "Incorrect permission to export" << LL_ENDL; - getInstance()->mExportState = EXPORT_FAILED; + llwarns << "Incorrect permission to export" << llendl; + self->mExportState = EXPORT_FAILED; LLSelectMgr::getInstance()->getSelection()->unref(); } else { LL_DEBUGS("ObjectBackup") << "Nodes permissions not yet received, delaying..." << LL_ENDL; - getInstance()->mExportState = EXPORT_CHECK_PERMS; + self->mExportState = EXPORT_CHECK_PERMS; } } } else { - LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED; + self->mExportState = EXPORT_ABORTED; LLSelectMgr::getInstance()->getSelection()->unref(); } break; @@ -525,9 +616,9 @@ void LLObjectBackup::exportWorker(void *userdata) { // Don't bother to try and fetch the extra physics flags if we // don't have sim support for them... - if (!getInstance()->mGotExtraPhysics) + if (!self->mGotExtraPhysics) { - getInstance()->mExportState = EXPORT_STRUCTURE; + self->mExportState = EXPORT_STRUCTURE; break; } @@ -536,7 +627,7 @@ void LLObjectBackup::exportWorker(void *userdata) virtual bool apply(LLSelectNode* node) { LLViewerObject* object = node->getObject(); - return object->getPhysicsShapeUnknown(); + return gObjectList.gotObjectPhysicsFlags(object); } } func; @@ -545,7 +636,7 @@ void LLObjectBackup::exportWorker(void *userdata) { if (LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func, false)) { - getInstance()->mExportState = EXPORT_STRUCTURE; + self->mExportState = EXPORT_STRUCTURE; } else { @@ -555,7 +646,7 @@ void LLObjectBackup::exportWorker(void *userdata) } else { - getInstance()->mExportState = EXPORT_FAILED; + self->mExportState = EXPORT_ABORTED; LLSelectMgr::getInstance()->getSelection()->unref(); } break; @@ -571,7 +662,9 @@ void LLObjectBackup::exportWorker(void *userdata) object->boostTexturePriority(true); LLViewerObject::child_list_t children = object->getChildren(); children.push_front(object); //push root onto list - LLSD prim_llsd = LLObjectBackup::getInstance()->primsToLLSD(children, is_attachment); + LLObjectBackup* self = findInstance(); + LLSD prim_llsd = self->primsToLLSD(children, + is_attachment); LLSD stuff; if (is_attachment) { @@ -584,77 +677,88 @@ void LLObjectBackup::exportWorker(void *userdata) stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); } stuff["group_body"] = prim_llsd; - getInstance()->mLLSD["data"].append(stuff); + self->mLLSD["data"].append(stuff); return true; } } func; - getInstance()->mExportState = EXPORT_LLSD; - LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); + LLViewerObject* object; + object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if (object) + { + self->mExportState = EXPORT_LLSD; + LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, false); + } + else + { + self->mExportState = EXPORT_ABORTED; + } LLSelectMgr::getInstance()->getSelection()->unref(); break; } case EXPORT_TEXTURES: { - if (!getInstance()->mCheckNextTexture) + if (!self->mCheckNextTexture) { // The texture is being fetched. Wait till next idle callback. return; } - if (getInstance()->mTexturesList.empty()) + if (self->mTexturesList.empty()) { - getInstance()->mExportState = EXPORT_DONE; + self->mExportState = EXPORT_DONE; return; } // Ok, we got work to do... - getInstance()->mCheckNextTexture= false; - getInstance()->exportNextTexture(); + self->mCheckNextTexture = false; + self->exportNextTexture(); break; } case EXPORT_LLSD: { // Create a file stream and write to it - llofstream export_file(getInstance()->mFileName); - LLSDSerialize::toPrettyXML(getInstance()->mLLSD, export_file); + llofstream export_file(self->mFileName); + LLSDSerialize::toPrettyXML(self->mLLSD, export_file); export_file.close(); - getInstance()->mCheckNextTexture = true; - getInstance()->mExportState = EXPORT_TEXTURES; + self->mCheckNextTexture = true; + self->mExportState = EXPORT_TEXTURES; break; } case EXPORT_DONE: { gIdleCallbacks.deleteFunction(exportWorker); - if (LLObjectBackup::getInstance()->mNonExportedTextures == LLObjectBackup::TEXTURE_OK) + if (self->mNonExportedTextures == LLObjectBackup::TEXTURE_OK) { - LL_INFOS("ObjectBackup") << "Export successful and complete." << LL_ENDL; + llinfos << "Export successful and complete." << llendl; LLNotificationsUtil::add("ExportSuccessful"); } else { - LL_INFOS("ObjectBackup") << "Export successful but incomplete: some texture(s) not saved." << LL_ENDL; + llinfos << "Export successful but incomplete: some texture(s) not saved." + << llendl; std::string reason; - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_PERM) + U32 error_bits_map = self->mNonExportedTextures; + if (error_bits_map & LLObjectBackup::TEXTURE_BAD_PERM) { reason += "\nBad permissions/creator."; } - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_MISSING) + if (error_bits_map & LLObjectBackup::TEXTURE_MISSING) { reason += "\nMissing texture (retrying after full rezzing might work)."; } - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_BAD_ENCODING) + if (error_bits_map & LLObjectBackup::TEXTURE_BAD_ENCODING) { reason += "\nBad texture encoding."; } - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_IS_NULL) + if (error_bits_map & LLObjectBackup::TEXTURE_IS_NULL) { reason += "\nNull texture."; } - if (getInstance()->mNonExportedTextures & LLObjectBackup::TEXTURE_SAVED_FAILED) + if (error_bits_map & LLObjectBackup::TEXTURE_SAVED_FAILED) { reason += "\nCould not write to disk."; } @@ -662,22 +766,32 @@ void LLObjectBackup::exportWorker(void *userdata) args["REASON"] = reason; LLNotificationsUtil::add("ExportPartial", args); } - getInstance()->close(); + self->destroy(); break; } case EXPORT_FAILED: { gIdleCallbacks.deleteFunction(exportWorker); - LL_WARNS("ObjectBackup") << "Export process aborted." << LL_ENDL; + llwarns << "Export process failed." << llendl; LLNotificationsUtil::add("ExportFailed"); - LLObjectBackup::getInstance()->close(); + self->destroy(); + break; + } + + case EXPORT_ABORTED: + { + gIdleCallbacks.deleteFunction(exportWorker); + llwarns << "Export process aborted." << llendl; + LLNotificationsUtil::add("ExportAborted"); + self->destroy(); break; } } } -LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool is_attachment) +LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, + bool is_attachment) { LLViewerObject* object; LLSD llsd; @@ -690,7 +804,7 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i object = (*i); LLUUID id = object->getID(); - LL_INFOS("ObjectBackup") << "Exporting prim " << object->getID().asString() << LL_ENDL; + llinfos << "Exporting prim " << object->getID().asString() << llendl; // Create an LLSD object that represents this prim. It will be injected // in to the overall LLSD tree structure @@ -753,27 +867,32 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i prim_llsd["volume"] = params.asLLSD(); // Extra paramsb6fab961-af18-77f8-cf08-f021377a7244 + if (object->isFlexible()) { // Flexible - LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); + LLFlexibleObjectData* flex; + flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); prim_llsd["flexible"] = flex->asLLSD(); } if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) { // Light - LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); + LLLightParams* light; + light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); prim_llsd["light"] = light->asLLSD(); } if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) { // Light image - LLLightImageParams* light_param = (LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + LLLightImageParams* light_param; + light_param = (LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); t_id = validateTextureID(light_param->getLightTexture()); if (mTexturesList.count(t_id) == 0) { - LL_INFOS("ObjectBackup") << "Found a light texture, adding to list " << t_id << LL_ENDL; + llinfos << "Found a light texture, adding to list " << t_id + << llendl; mTexturesList.insert(t_id); } prim_llsd["light_texture"] = light_param->asLLSD(); @@ -782,7 +901,8 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) { // Sculpt - LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLSculptParams* sculpt; + sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); prim_llsd["sculpt"] = sculpt->asLLSD(); if ((sculpt->getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) { @@ -791,14 +911,16 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i { if (mTexturesList.count(sculpt_texture) == 0) { - LL_INFOS("ObjectBackup") << "Found a sculpt texture, adding to list " << sculpt_texture << LL_ENDL; + llinfos << "Found a sculpt texture, adding to list " + << sculpt_texture << llendl; mTexturesList.insert(sculpt_texture); } } else { - LL_WARNS("ObjectBackup") << "Incorrect permission to export a sculpt texture." << LL_ENDL; - getInstance()->mExportState = EXPORT_FAILED; + llwarns << "Incorrect permission to export a sculpt texture." + << llendl; + mExportState = EXPORT_FAILED; } } } @@ -819,12 +941,8 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i this_te_llsd = te->asLLSD(); this_te_llsd["imageid"] = t_id; te_llsd.append(this_te_llsd); - // Do not export Linden textures even though they don't taint creation. - if (t_id != LL_TEXTURE_PLYWOOD && - t_id != LL_TEXTURE_BLANK && - t_id != LL_TEXTURE_TRANSPARENT && - t_id != LL_TEXTURE_INVISIBLE && - t_id != LL_TEXTURE_MEDIA) + // Do not export non-existent default textures + if (t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE) { if (mTexturesList.count(t_id) == 0) { @@ -862,8 +980,9 @@ LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool i prim_llsd["materials"] = te_mat_llsd; } - // The keys in the primitive maps do not have to be localids, they can be any - // string. We simply use localids because they are a unique identifier + // The keys in the primitive maps do not have to be localids, they can + // be any string. We simply use localids because they are a unique + // identifier snprintf(localid, sizeof(localid), "%u", object->getLocalID()); llsd[(const char*)localid] = prim_llsd; } @@ -882,7 +1001,7 @@ void LLObjectBackup::exportNextTexture() if (mTexturesList.empty()) { mCheckNextTexture = true; - LL_INFOS("ObjectBackup") << "Finished exporting textures." << LL_ENDL; + llinfos << "Finished exporting textures." << llendl; return; } if (iter == mTexturesList.end()) @@ -929,7 +1048,7 @@ void LLObjectBackup::exportNextTexture() } else { - LL_WARNS("ObjectBackup") << "We *DON'T* have the texture " << id.asString() << LL_ENDL; + llwarns << "We *DON'T* have the texture " << id << llendl; mNonExportedTextures |= TEXTURE_MISSING; mTexturesList.erase(id); } @@ -937,10 +1056,20 @@ void LLObjectBackup::exportNextTexture() mTexturesList.erase(id); - LL_INFOS("ObjectBackup") << "Requesting texture " << id << LL_ENDL; + llinfos << "Requesting texture " << id << " from cache." << llendl; LLImageJ2C* mFormattedImage = new LLImageJ2C; - CacheReadResponder* responder = new CacheReadResponder(id, mFormattedImage); - LLAppViewer::getTextureCache()->readFromCache(id, LLWorkerThread::PRIORITY_HIGH, 0, 999999, responder); + BackupCacheReadResponder* responder; + responder = new BackupCacheReadResponder(id, mFormattedImage); + LLAppViewer::getTextureCache()->readFromCache(id, + LLWorkerThread::PRIORITY_HIGH, + 0, 999999, responder); +} + + +bool is_default_texture(const LLUUID& id) +{ + return id.isNull() || id == LL_TEXTURE_PLYWOOD || id == LL_TEXTURE_BLANK || + id == LL_TEXTURE_INVISIBLE; } void LLObjectBackup::importObject(bool upload) @@ -949,7 +1078,7 @@ void LLObjectBackup::importObject(bool upload) mTexturesList.clear(); mAssetMap.clear(); mCurrentAsset.setNull(); - + mGotExtraPhysics = !gAgent.getRegion()->getCapability("GetObjectPhysicsData").empty(); setDefaultTextures(); @@ -975,18 +1104,19 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) import_file.close(); if (!mLLSD.has("data")) { - LLNotificationsUtil::add("InvalidObjectParams"); - close(); + LLNotificationsUtil::add("ImportFailed"); + destroy(); return; } - show(false); + showFloater(false); mAgentPos = gAgent.getPositionAgent(); mAgentRot = LLQuaternion(gAgent.getAtAxis(), gAgent.getLeftAxis(), gAgent.getUpAxis()); // Get the texture map + mCurObject = 1; mCurPrim = 1; mObjects = mLLSD["data"].size(); @@ -1014,14 +1144,31 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) LLUUID orig = sculpt.getSculptTexture(); if (mTexturesList.count(orig) == 0) { - LL_INFOS("ObjectBackup") << "Found a new SCULPT texture to upload " << orig << LL_ENDL; + llinfos << "Found a new SCULPT texture to upload " + << orig << llendl; mTexturesList.insert(orig); } } } - LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] : prim_llsd["texture"]; // Firestorm's format uses singular "texture" + if (prim_llsd.has("light_texture")) + { + LLLightImageParams lightimg; + lightimg.fromLLSD(prim_llsd["light_texture"]); + LLUUID t_id = lightimg.getLightTexture(); + if (!is_default_texture(t_id) && + mTexturesList.count(t_id) == 0) + { + llinfos << "Found a new light texture to upload: " << t_id + << llendl; + mTexturesList.insert(t_id); + } + } + // Check both for "textures" and "texture" since the second (buggy) + // case has already been seen in some exported prims XML files... + LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] + : prim_llsd["texture"]; for (LLSD::array_iterator it = te_llsd.beginArray(); it != te_llsd.endArray(); ++it) { @@ -1030,14 +1177,12 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) te.fromLLSD(the_te); LLUUID t_id = te.getID(); - // Do not upload the default textures - if (t_id != LL_TEXTURE_PLYWOOD && t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE) // Do not upload the default textures + if (!is_default_texture(t_id) && + mTexturesList.count(t_id) == 0) { - if (mTexturesList.count(t_id) == 0) - { - LL_INFOS("ObjectBackup") << "Found a new texture to upload: "<< t_id << LL_ENDL; + llinfos << "Found a new texture to upload: " << t_id + << llendl; mTexturesList.insert(t_id); - } } } @@ -1052,29 +1197,21 @@ void LLObjectBackup::importObject_continued(AIFilePicker* filepicker) mat.fromLLSD(the_mat); LLUUID t_id = mat.getNormalID(); - if (t_id.notNull() && t_id != LL_TEXTURE_PLYWOOD && - t_id != LL_TEXTURE_BLANK && - t_id != LL_TEXTURE_INVISIBLE) + if (!is_default_texture(t_id) && + mTexturesList.count(t_id) == 0) { - if (mTexturesList.count(t_id) == 0) - { - LL_INFOS("ObjectBackup") << "Found a new normal map to upload: " - << t_id << LL_ENDL; - mTexturesList.insert(t_id); - } + llinfos << "Found a new normal map to upload: " + << t_id << llendl; + mTexturesList.insert(t_id); } t_id = mat.getSpecularID(); - if (t_id.notNull() && t_id != LL_TEXTURE_PLYWOOD && - t_id != LL_TEXTURE_BLANK && - t_id != LL_TEXTURE_INVISIBLE) + if (!is_default_texture(t_id) && + mTexturesList.count(t_id) == 0) { - if (mTexturesList.count(t_id) == 0) - { - LL_INFOS("ObjectBackup") << "Found a new specular map to upload: " - << t_id << LL_ENDL; - mTexturesList.insert(t_id); - } + llinfos << "Found a new specular map to upload: " + << t_id << llendl; + mTexturesList.insert(t_id); } } } @@ -1107,9 +1244,9 @@ void LLObjectBackup::rezAgentOffset(LLVector3 offset) void LLObjectBackup::importFirstObject() { mRunning = true; - show(false); + showFloater(false); mGroupPrimImportIter = mLLSD["data"].beginArray(); - mRootRootPos = (*mGroupPrimImportIter)["root_position"]; + mRootRootPos = LLVector3((*mGroupPrimImportIter)["root_position"]); mObjects = mLLSD["data"].size(); mCurObject = 1; importNextObject(); @@ -1127,7 +1264,7 @@ void LLObjectBackup::importNextObject() mPrims = mThisGroup.size(); updateImportNumbers(); - LLVector3 lgpos = (*mGroupPrimImportIter)["root_position"]; + LLVector3 lgpos = LLVector3((*mGroupPrimImportIter)["root_position"]); mGroupOffset = lgpos - mRootRootPos; mRootPos = offsetAgent(LLVector3(2.0, 0.0, 0.0)); mRootRot = ll_quaternion_from_sd((*mGroupPrimImportIter)["root_rotation"]); @@ -1168,7 +1305,7 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) if (prim_llsd.has("parent")) { //we are not the root node. - LLVector3 pos = prim_llsd["position"]; + LLVector3 pos = LLVector3(prim_llsd["position"]); LLQuaternion rot = ll_quaternion_from_sd(prim_llsd["rotation"]); object->setPositionRegion(pos * mRootRot + mRootPos + mGroupOffset); object->setRotation(rot * mRootRot); @@ -1180,11 +1317,11 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) object->setRotation(rot); } - object->setScale(prim_llsd["scale"]); + object->setScale(LLVector3(prim_llsd["scale"])); if (prim_llsd.has("flags")) { - U32 flags(prim_llsd["flags"].asInteger()); + U32 flags = (U32)prim_llsd["flags"].asInteger(); object->setFlags(flags, true); } else // Kept for backward compatibility @@ -1228,12 +1365,12 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLSculptParams sculpt; sculpt.fromLLSD(prim_llsd["sculpt"]); - // TODO: check if map is valid and only set texture if map is valid and changes - - if (mAssetMap.count(sculpt.getSculptTexture())) + // TODO: check if map is valid and only set texture if map is valid and + // changes + LLUUID t_id = sculpt.getSculptTexture(); + if (mAssetMap.count(t_id)) { - LLUUID replacement = mAssetMap[sculpt.getSculptTexture()]; - sculpt.setSculptTexture(replacement); + sculpt.setSculptTexture(mAssetMap[t_id]); } object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt, true); @@ -1250,7 +1387,13 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) // Light image LLLightImageParams lightimg; lightimg.fromLLSD(prim_llsd["light_texture"]); - object->setParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE, lightimg, true); + LLUUID t_id = lightimg.getLightTexture(); + if (mAssetMap.count(t_id)) + { + lightimg.setLightTexture(mAssetMap[t_id]); + } + object->setParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE, lightimg, + true); } if (prim_llsd.has("flexible")) @@ -1261,8 +1404,11 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) } // Textures - LL_INFOS("ObjectBackup") << "Processing textures for prim" << id << LL_ENDL; - LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] : prim_llsd["texture"]; // Firestorm's format uses singular "texture" + // Check both for "textures" and "texture" since the second (buggy) case + // has already been seen in some exported prims XML files... + llinfos << "Processing textures for prim" << id << llendl; + LLSD& te_llsd = prim_llsd.has("textures") ? prim_llsd["textures"] + : prim_llsd["texture"]; U8 i = 0; for (LLSD::array_iterator it = te_llsd.beginArray(); it != te_llsd.endArray(); ++it) @@ -1273,18 +1419,17 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLUUID t_id = te.getID(); if (mAssetMap.count(t_id)) { - LLUUID replacement = mAssetMap[t_id]; - te.setID(replacement); + te.setID(mAssetMap[t_id]); } object->setTE(i++, te); } - LL_INFOS("ObjectBackup") << "Textures done !" << LL_ENDL; + llinfos << "Textures done !" << llendl; // Materials if (prim_llsd.has("materials")) { - LL_INFOS("ObjectBackup") << "Processing materials for prim " << id << LL_ENDL; + llinfos << "Processing materials for prim " << id << llendl; te_llsd = prim_llsd["materials"]; i = 0; for (LLSD::array_iterator it = te_llsd.beginArray(); @@ -1296,20 +1441,18 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLUUID t_id = mat->getNormalID(); if (id.notNull() && mAssetMap.count(t_id)) { - LLUUID replacement = mAssetMap[t_id]; - mat->setNormalID(replacement); + mat->setNormalID(mAssetMap[t_id]); } t_id = mat->getSpecularID(); if (id.notNull() && mAssetMap.count(t_id)) { - LLUUID replacement = mAssetMap[t_id]; - mat->setSpecularID(replacement); + mat->setSpecularID(mAssetMap[t_id]); } LLMaterialMgr::getInstance()->put(id, i++, *mat); } - LL_INFOS("ObjectBackup") << "Materials done !" << LL_ENDL; + llinfos << "Materials done !" << llendl; } object->sendRotationUpdate(); @@ -1320,107 +1463,110 @@ void LLObjectBackup::xmlToPrim(LLSD prim_llsd, LLViewerObject* object) LLSelectMgr::getInstance()->deselectAll(); } -// This is fired when the update packet is processed so we know the prim settings have stuck +// This is fired when the update packet is processed so we know the prim +// settings have stuck +//static void LLObjectBackup::primUpdate(LLViewerObject* object) { - if (!mRunning || (object != NULL && object->mID != mExpectingUpdate)) + LLObjectBackup* self = findInstance(); + if (!object || !self || !self->mRunning || + object->mID != self->mExpectingUpdate) { return; } - ++mCurPrim; - updateImportNumbers(); - ++mPrimImportIter; + ++self->mCurPrim; + self->updateImportNumbers(); + ++self->mPrimImportIter; - LLUUID x; - mExpectingUpdate = x.null; + self->mExpectingUpdate.setNull(); - if (mPrimImportIter == mThisGroup.endMap()) + if (self->mPrimImportIter == self->mThisGroup.endMap()) { - LL_INFOS("ObjectBackup") << "Trying to link" << LL_ENDL; + llinfos << "Trying to link..." << llendl; - if (mToSelect.size() > 1) + if (self->mToSelect.size() > 1) { - std::reverse(mToSelect.begin(), mToSelect.end()); + std::reverse(self->mToSelect.begin(), self->mToSelect.end()); // Now link LLSelectMgr::getInstance()->deselectAll(); - LLSelectMgr::getInstance()->selectObjectAndFamily(mToSelect, true); + LLSelectMgr::getInstance()->selectObjectAndFamily(self->mToSelect, true); LLSelectMgr::getInstance()->sendLink(); - LLViewerObject* root = mToSelect.back(); - root->setRotation(mRootRot); + LLViewerObject* root = self->mToSelect.back(); + root->setRotation(self->mRootRot); } - ++mCurObject; - ++mGroupPrimImportIter; - if (mGroupPrimImportIter != mLLSD["data"].endArray()) + ++self->mCurObject; + ++self->mGroupPrimImportIter; + if (self->mGroupPrimImportIter != self->mLLSD["data"].endArray()) { - importNextObject(); + self->importNextObject(); return; } - mRunning = false; - close(); + self->mRunning = false; + self->destroy(); return; } - LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; + LLSD prim_llsd = self->mThisGroup[self->mPrimImportIter->first]; - if (mToSelect.empty()) + if (self->mToSelect.empty()) { - LL_WARNS("ObjectBackup") << "error: ran out of objects to mod." << LL_ENDL; - mRunning = false; - close(); + llwarns << "error: ran out of objects to mod." << llendl; + self->mRunning = false; + self->destroy(); return; } - if (mPrimImportIter != mThisGroup.endMap()) + if (self->mPrimImportIter != self->mThisGroup.endMap()) { //rezAgentOffset(LLVector3(1.0, 0.0, 0.0)); - LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; - ++mProcessIter; - xmlToPrim(prim_llsd, *mProcessIter); + LLSD prim_llsd =self-> mThisGroup[self->mPrimImportIter->first]; + ++self->mProcessIter; + self->xmlToPrim(prim_llsd, *(self->mProcessIter)); } } // Callback when we rez a new object when the importer is running. -bool LLObjectBackup::newPrim(LLViewerObject* pobject) +//static +void LLObjectBackup::newPrim(LLViewerObject* object) { - if (mRunning) + LLObjectBackup* self = findInstance(); + if (!object || !self || !self->mRunning) return; + + ++self->mRezCount; + self->mToSelect.push_back(object); + self->updateImportNumbers(); + ++self->mPrimImportIter; + + object->setPosition(self->offsetAgent(LLVector3(0.0, 1.0, 0.0))); + LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); + + if (self->mPrimImportIter != self->mThisGroup.endMap()) { - ++mRezCount; - mToSelect.push_back(pobject); - updateImportNumbers(); - ++mPrimImportIter; - - pobject->setPosition(offsetAgent(LLVector3(0.0, 1.0, 0.0))); - LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); - - if (mPrimImportIter != mThisGroup.endMap()) - { - rezAgentOffset(LLVector3(1.0, 0.0 ,0.0)); - } - else - { - LL_INFOS("ObjectBackup") << "All prims rezzed, moving to build stage" << LL_ENDL; - // Deselecting is required to ensure that the first child prim in - // the link set (which is also the last rezzed prim and thus - // currently selected) will be properly renamed and desced. - LLSelectMgr::getInstance()->deselectAll(); - mPrimImportIter = mThisGroup.beginMap(); - LLSD prim_llsd = mThisGroup[mPrimImportIter->first]; - mProcessIter = mToSelect.begin(); - xmlToPrim(prim_llsd, *mProcessIter); - } + self->rezAgentOffset(LLVector3(1.0, 0.0 ,0.0)); + } + else + { + llinfos << "All prims rezzed, moving to build stage" << llendl; + // Deselecting is required to ensure that the first child prim in + // the link set (which is also the last rezzed prim and thus + // currently selected) will be properly renamed and desced. + LLSelectMgr::getInstance()->deselectAll(); + self->mPrimImportIter = self->mThisGroup.beginMap(); + LLSD prim_llsd = self->mThisGroup[self->mPrimImportIter->first]; + self->mProcessIter = self->mToSelect.begin(); + self->xmlToPrim(prim_llsd, *(self->mProcessIter)); } - return true; } void LLObjectBackup::updateMap(LLUUID uploaded_asset) { if (mCurrentAsset.notNull()) { - LL_INFOS("ObjectBackup") << "Mapping " << mCurrentAsset << " to " << uploaded_asset << LL_ENDL; - + llinfos << "Mapping " << mCurrentAsset << " to " << uploaded_asset + << llendl; mAssetMap[mCurrentAsset] = uploaded_asset; } } @@ -1445,8 +1591,7 @@ void myupload_new_resource(const LLTransactionID &tid, LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); // At this point, we're ready for the upload. - std::string upload_message = "Uploading...\n\n"; - upload_message.append(display_name); + std::string upload_message = "Uploading texture:\n\n" + display_name; LLUploadDialog::modalUploadDialog(upload_message); std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); @@ -1463,12 +1608,15 @@ void myupload_new_resource(const LLTransactionID &tid, std::ostringstream llsdxml; LLSDSerialize::toXML(body, llsdxml); - LL_DEBUGS("ObjectBackup") << "posting body to capability: " << llsdxml.str() << LL_ENDL; - LLHTTPClient::post(url, body, new importResponder(body, uuid, asset_type)); + LL_DEBUGS("ObjectBackup") << "posting body to capability: " + << llsdxml.str() << LL_ENDL; + LLHTTPClient::post(url, body, + new ImportObjectResponder(body, uuid, asset_type)); } else { - LL_INFOS("ObjectBackup") << "NewAgentInventory capability not found. Can't upload !" << LL_ENDL; + llinfos << "NewAgentInventory capability not found. Can't upload !" + << llendl; } } @@ -1476,7 +1624,7 @@ void LLObjectBackup::uploadNextAsset() { if (mTexturesList.empty()) { - LL_INFOS("ObjectBackup") << "Texture list is empty, moving to rez stage." << LL_ENDL; + llinfos << "Texture list is empty, moving to rez stage." << llendl; mCurrentAsset.setNull(); importFirstObject(); return; @@ -1488,7 +1636,7 @@ void LLObjectBackup::uploadNextAsset() LLUUID id = *iter; mTexturesList.erase(iter); - LL_INFOS("ObjectBackup") << "Got texture ID " << id << ": trying to upload..." << LL_ENDL; + llinfos << "Got texture ID " << id << ": trying to upload..." << llendl; mCurrentAsset = id; std::string struid; @@ -1517,7 +1665,7 @@ void LLObjectBackup::uploadNextAsset() } else { - LL_WARNS("ObjectBackup") << "Unable to access output file " << filename << LL_ENDL; + llwarns << "Unable to access output file " << filename << llendl; uploadNextAsset(); return; } @@ -1525,5 +1673,5 @@ void LLObjectBackup::uploadNextAsset() myupload_new_resource(tid, LLAssetType::AT_TEXTURE, struid, struid, 0, LLFolderType::FT_TEXTURE, LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), - 0x0, "Uploaded texture", NULL, NULL); + 0x0, struid, NULL, NULL); } diff --git a/indra/newview/llviewerobjectbackup.h b/indra/newview/llviewerobjectbackup.h index 2b29d91fd..2b2283dff 100644 --- a/indra/newview/llviewerobjectbackup.h +++ b/indra/newview/llviewerobjectbackup.h @@ -30,10 +30,22 @@ #ifndef LL_LLVIEWEROBJECTBACKUP_H #define LL_LLVIEWEROBJECTBACKUP_H +#include +#include +#include + #include "boost/unordered_map.hpp" #include "boost/unordered_set.hpp" +#include "llfloater.h" +#include "statemachine/aifilepicker.h" +#include "lluuid.h" + #include "llviewerinventory.h" +#include "llviewerobject.h" + +class LLSelectNode; +class LLViewerObject; enum export_states { EXPORT_INIT, @@ -43,24 +55,27 @@ enum export_states { EXPORT_TEXTURES, EXPORT_LLSD, EXPORT_DONE, - EXPORT_FAILED + EXPORT_FAILED, + EXPORT_ABORTED }; -class LLObjectBackup : public LLFloater +class LLObjectBackup : public LLFloater, + public LLFloaterSingleton { + friend class LLUISingleton >; + +protected: + LOG_CLASS(LLObjectBackup); + public: - virtual ~LLObjectBackup(); + /////////////////////////////////////////////////////////////////////////// + // LLFloater interface - // Floater stuff - virtual void show(bool exporting); - virtual void onClose(bool app_quitting); + /*virtual*/ ~LLObjectBackup(); + /*virtual*/ void onClose(bool app_quitting); - // Static accessor - static LLObjectBackup* getInstance(); - static bool instanceExists() { return sInstance != NULL; } - - // Export idle callback - static void exportWorker(void *userdata); + /////////////////////////////////////////////////////////////////////////// + // Public interface for invoking the object backup feature // Import entry point void importObject(bool upload = false); @@ -70,47 +85,44 @@ public: void exportObject(); void exportObject_continued(AIFilePicker* filepicker); + /////////////////////////////////////////////////////////////////////////// + // Public methods used in callbacks, workers and responders + // Update map from texture worker void updateMap(LLUUID uploaded_asset); - // Move to next texture upload + // Move to next texture upload, called by the agent inventory responder void uploadNextAsset(); - // Folder public geter - std::string getfolder() { return mFolder; } + // Export idle callback + static void exportWorker(void *userdata); - // Prim updated callback - void primUpdate(LLViewerObject* object); + // Prim updated callback, called in llviewerobjectlist.cpp + static void primUpdate(LLViewerObject* object); - // New prim call back - bool newPrim(LLViewerObject* pobject); + // New prim call back, called in llviewerobjectlist.cpp + static void newPrim(LLViewerObject* object); - static const U32 TEXTURE_OK = 0x00; - static const U32 TEXTURE_BAD_PERM = 0x01; - static const U32 TEXTURE_MISSING = 0x02; - static const U32 TEXTURE_BAD_ENCODING = 0x04; - static const U32 TEXTURE_IS_NULL = 0x08; - static const U32 TEXTURE_SAVED_FAILED = 0x10; + // Folder public getter, used by the texture cache responder + std::string getFolder() { return mFolder; } - // Set when the region supports the extra physics flags - bool mGotExtraPhysics; - - // Are we ready to check for next texture? - bool mCheckNextTexture; - - // Export state machine - enum export_states mExportState; - - // Export result flags for textures. - U32 mNonExportedTextures; static void setDefaultTextures(); - // Is exporting these objects allowed - bool validatePerms(const LLPermissions* item_permissions); + // Permissions checking + static bool validatePerms(const LLPermissions* item_permissions); + static bool validateTexturePerms(const LLUUID& asset_id); + static bool validateNode(LLSelectNode* node); private: - LLObjectBackup(); + // Open only via the importObject() and exportObject() methods defined + // above. + LLObjectBackup(const LLSD&); + + void showFloater(bool exporting); + + static bool confirmCloseCallback(const LLSD& notification, + const LLSD& response); // Update the floater with status numbers void updateImportNumbers(); @@ -133,7 +145,7 @@ private: void exportNextTexture(); // Apply LLSD to object - void xmlToPrim(LLSD prim_llsd, LLViewerObject* pobject); + void xmlToPrim(LLSD prim_llsd, LLViewerObject* object); // Rez a prim at a given position void rezAgentOffset(LLVector3 offset); @@ -141,9 +153,28 @@ private: // Get an offset from the agent based on rotation and current pos LLVector3 offsetAgent(LLVector3 offset); -private: - static LLObjectBackup* sInstance; +public: + // Public static constants, used in callbacks, workers and responders + static const U32 TEXTURE_OK = 0x00; + static const U32 TEXTURE_BAD_PERM = 0x01; + static const U32 TEXTURE_MISSING = 0x02; + static const U32 TEXTURE_BAD_ENCODING = 0x04; + static const U32 TEXTURE_IS_NULL = 0x08; + static const U32 TEXTURE_SAVED_FAILED = 0x10; + // Export state machine + enum export_states mExportState; + + // Export result flags for textures. + U32 mNonExportedTextures; + + // Set when the region supports the extra physics flags + bool mGotExtraPhysics; + + // Are we ready to check for next texture? + bool mCheckNextTexture; + +private: // Are we active flag bool mRunning; @@ -156,7 +187,7 @@ private: U32 mPrims; U32 mCurPrim; - // No prims rezed + // Number of rezzed prims U32 mRezCount; // Root pos and rotation and central root pos for link set @@ -168,31 +199,39 @@ private: // Agent inital pos and rot when starting import LLVector3 mAgentPos; LLQuaternion mAgentRot; - // Rebase map - boost::unordered_map mAssetMap; + + LLUUID mCurrentAsset; + LLUUID mExpectingUpdate; + + // Working llsd iterators for objects and linksets + LLSD::map_const_iterator mPrimImportIter; + LLSD::array_const_iterator mGroupPrimImportIter; + + // File and folder name control + std::string mFileName; + std::string mFolder; // Export texture list typedef boost::unordered_set textures_set_t; textures_set_t mTexturesList; textures_set_t mBadPermsTexturesList; + // Rebase map + boost::unordered_map mAssetMap; + // Import object tracking std::vector mToSelect; std::vector::iterator mProcessIter; - // File and folder name control - std::string mFileName; - std::string mFolder; - // Working LLSD holders - LLUUID mCurrentAsset; - LLUUID mExpectingUpdate; LLSD mLLSD; LLSD mThisGroup; - - // Working llsd itterators for objects and linksets - LLSD::map_const_iterator mPrimImportIter; - LLSD::array_const_iterator mGroupPrimImportIter; }; -#endif \ No newline at end of file +extern LLUUID LL_TEXTURE_PLYWOOD; +extern LLUUID LL_TEXTURE_BLANK; +extern LLUUID LL_TEXTURE_INVISIBLE; +extern LLUUID LL_TEXTURE_TRANSPARENT; +extern LLUUID LL_TEXTURE_MEDIA; + +#endif // LL_LLVIEWEROBJECTBACKUP_H diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 2f9317090..d76659943 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -272,7 +272,7 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, } else { - LLObjectBackup::getInstance()->primUpdate(objectp); + LLObjectBackup::primUpdate(objectp); } @@ -310,7 +310,7 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, gViewerWindow->getWindow()->decBusyCount(); gViewerWindow->getWindow()->setCursor( UI_CURSOR_ARROW ); - LLObjectBackup::getInstance()->newPrim(objectp); + LLObjectBackup::newPrim(objectp); } } @@ -1216,6 +1216,17 @@ void LLViewerObjectList::fetchPhysicsFlags() } } +bool LLViewerObjectList::gotObjectPhysicsFlags(LLViewerObject* objectp) +{ + // This will insert objectp in mStalePhysicsFlags if needed: + objectp->getPhysicsShapeType(); + // Data has been retrieved if the object is not in either of the + // two lists: + const LLUUID& id = objectp->getID(); + return mPendingPhysicsFlags.count(id) == 0 && + mStalePhysicsFlags.count(id) == 0; +} + void LLViewerObjectList::clearDebugText() { for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index c5b6b98f6..516c3d1e1 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -99,6 +99,8 @@ public: void fetchObjectCosts(); void fetchPhysicsFlags(); + bool gotObjectPhysicsFlags(LLViewerObject* objectp); + void updateObjectCost(LLViewerObject* object); void updateObjectCost(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost); void onObjectCostFetchFailure(const LLUUID& object_id); diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index cbf32eb43..f563c4062 100644 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp @@ -361,6 +361,51 @@ BOOL LLViewerTexLayerSetBuffer::requestUpdateImmediate() return result; } +class LLSendTexLayerResponder : public LLAssetUploadResponder +{ + LOG_CLASS(LLSendTexLayerResponder); +public: + LLSendTexLayerResponder(const LLSD& post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type, LLBakedUploadData * baked_upload_data) + : LLAssetUploadResponder(post_data, vfile_id, asset_type) + , mBakedUploadData(baked_upload_data) + {} + + ~LLSendTexLayerResponder() + { + // mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below + if (mBakedUploadData) + { // ...but delete it in the case where uploadComplete() is never called + delete mBakedUploadData; + mBakedUploadData = NULL; + } + } + + // Baked texture upload completed + /*virtual*/ void uploadComplete(const LLSD& content) + { + const std::string& result = content["state"]; + const LLUUID& new_id = content["new_asset"]; + + llinfos << "result: " << result << " new_id: " << new_id << llendl; + LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, (result == "complete" && mBakedUploadData) ? 0 : -1, LL_EXSTAT_NONE); + mBakedUploadData = NULL; // deleted in onTextureUploadComplete() + } + + /*virtual*/ void httpFailure() + { + llinfos << dumpResponse() << llendl; + + // Invoke the original callback with an error result + LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID::null, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE); + mBakedUploadData = NULL; // deleted in onTextureUploadComplete() + } + + /*virtual*/ char const* getName() const { return "LLSendTexLayerResponder"; } + +private: + LLBakedUploadData* mBakedUploadData; +}; + // Create the baked texture, send it out to the server, then wait for it to come // back so we can switch to using it. void LLViewerTexLayerSetBuffer::doUpload() diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 9e20f8ab8..95b24f7d7 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1799,10 +1799,10 @@ void LLVOAvatar::renderCollisionVolumes() { std::ostringstream ostr; LLGLDepthTest gls_depth(GL_FALSE); - for (S32 i = 0; i < mNumCollisionVolumes; i++) + for (S32 i = 0; i < (S32)mCollisionVolumes.size(); i++) { - mCollisionVolumes[i].renderCollision(); - ostr << mCollisionVolumes[i].getName() << ", "; + mCollisionVolumes[i]->renderCollision(); + ostr << mCollisionVolumes[i]->getName() << ", "; } if (mNameText.notNull()) @@ -1920,11 +1920,11 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& if (lineSegmentBoundingBox(start, end)) { - for (S32 i = 0; i < mNumCollisionVolumes; ++i) + for (S32 i = 0; i < (S32)mCollisionVolumes.size(); ++i) { - mCollisionVolumes[i].updateWorldMatrix(); + mCollisionVolumes[i]->updateWorldMatrix(); - const LLMatrix4a& mat = mCollisionVolumes[i].getXform()->getWorldMatrix(); + const LLMatrix4a& mat = mCollisionVolumes[i]->getXform()->getWorldMatrix(); LLMatrix4a inverse = mat; inverse.invert(); LLMatrix4a norm_mat = inverse; diff --git a/indra/newview/skins/default/xui/en-us/floater_object_backup.xml b/indra/newview/skins/default/xui/en-us/floater_object_backup.xml index 060c4421e..dc9390ed8 100644 --- a/indra/newview/skins/default/xui/en-us/floater_object_backup.xml +++ b/indra/newview/skins/default/xui/en-us/floater_object_backup.xml @@ -1,6 +1,14 @@ - - Progress + + + Progress + + + Object export + + + Object import + diff --git a/indra/newview/skins/default/xui/en-us/menu_radar.xml b/indra/newview/skins/default/xui/en-us/menu_radar.xml index 2f06bbf3c..624b577c6 100644 --- a/indra/newview/skins/default/xui/en-us/menu_radar.xml +++ b/indra/newview/skins/default/xui/en-us/menu_radar.xml @@ -119,6 +119,10 @@ + + + + diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index f1315772a..5284cbd0f 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -5938,11 +5938,25 @@ A login URI is required to retrieve the grid info. Builds with extended hollow or extended hole size do not render properly on other viewers. Please keep this option checked, if you want your builds looking properly in other viewers. + +Bad XML file. Import aborted. + + + +The Object was deselected before the export could occur. Export aborted. + + -None of the selected objects are exportable. Export aborted. +Bad permissions for the exported object. Export aborted. + +Are you sure you want to abort the current object backup operation? +
+