diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index f2f1b1157c..11b33e573c 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -348,7 +348,7 @@ void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& calla try { // Disable for more meaningful callstacks -//#if LL_WINDOWS +//#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD // winlevel(callable); //#else // diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 4d73533797..ba5b36a47f 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -2203,19 +2203,27 @@ bool LLImageFormatted::load(const std::string &filename, int load_size) } bool res; U8 *data = allocateData(load_size); - apr_size_t bytes_read = load_size; - apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read - if (s != APR_SUCCESS || (S32) bytes_read != load_size) + if (data) { - deleteData(); - setLastError("Unable to read file",filename); - res = false; + apr_size_t bytes_read = load_size; + apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read + if (s != APR_SUCCESS || (S32) bytes_read != load_size) + { + deleteData(); + setLastError("Unable to read file",filename); + res = false; + } + else + { + res = updateData(); + } } else { - res = updateData(); + setLastError("Allocation failure", filename); + res = false; } - + return res; } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index b61fd2ebc3..eeef62603c 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2349,7 +2349,14 @@ bool idle_startup() if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT) { LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL; - LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); + if (gRememberPassword) + { + LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); + } + else + { + LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status); + } reset_login(); } return FALSE; @@ -3252,7 +3259,14 @@ void use_circuit_callback(void**, S32 result) { // Make sure user knows something bad happened. JC LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL; - LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); + if (gRememberPassword) + { + LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status); + } + else + { + LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status); + } reset_login(); } else diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index d8aa49ab07..933ded9aaa 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -748,9 +748,14 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask) !objectp->isHUDAttachment() && objectp->getRoot() == gAgentAvatarp->getRoot()) { - // force focus to point in space where we were looking previously - gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null); - gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + // we are essentially editing object position + if (!gSavedSettings.getBOOL("EditCameraMovement")) + { + // force focus to point in space where we were looking previously + // Example of use: follow cam scripts shouldn't affect you when movng objects arouns + gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null); + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + } } else { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 633029dee8..2520348ea3 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -287,6 +287,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mPixelArea(1024.f), mInventory(NULL), mInventorySerialNum(0), + mExpectedInventorySerialNum(0), mInvRequestState(INVENTORY_REQUEST_STOPPED), mInvRequestXFerId(0), mInventoryDirty(FALSE), @@ -2899,13 +2900,13 @@ void LLViewerObject::doUpdateInventory( { // best guess. perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic); - --mInventorySerialNum; + --mExpectedInventorySerialNum; } else { // dummy it up. perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic); - --mInventorySerialNum; + --mExpectedInventorySerialNum; } } LLViewerInventoryItem* oldItem = item; @@ -2913,7 +2914,11 @@ void LLViewerObject::doUpdateInventory( new_item->setPermissions(perm); mInventory->push_front(new_item); doInventoryCallback(); - ++mInventorySerialNum; + ++mExpectedInventorySerialNum; + } + else if (is_new) + { + ++mExpectedInventorySerialNum; } } @@ -2980,7 +2985,7 @@ void LLViewerObject::moveInventory(const LLUUID& folder_id, if(!item->getPermissions().allowCopyBy(gAgent.getID())) { deleteInventoryItem(item_id); - ++mInventorySerialNum; + ++mExpectedInventorySerialNum; } } } @@ -3256,74 +3261,95 @@ S32 LLFilenameAndTask::sCount = 0; // static void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) { - LLUUID task_id; - msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id); - LLViewerObject* object = gObjectList.findObject(task_id); - if(!object) - { - LL_WARNS() << "LLViewerObject::processTaskInv object " - << task_id << " does not exist." << LL_ENDL; - return; - } + LLUUID task_id; + msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id); + LLViewerObject* object = gObjectList.findObject(task_id); + if (!object) + { + LL_WARNS() << "LLViewerObject::processTaskInv object " + << task_id << " does not exist." << LL_ENDL; + return; + } - LLFilenameAndTask* ft = new LLFilenameAndTask; - ft->mTaskID = task_id; - // we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update - msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial); + LLFilenameAndTask* ft = new LLFilenameAndTask; + ft->mTaskID = task_id; + // we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update + msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial); - if (ft->mSerial < object->mInventorySerialNum) - { - // viewer did some changes to inventory that were not saved yet. - LL_DEBUGS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client serial: " << object->mInventorySerialNum << LL_ENDL; - object->mInventorySerialNum = ft->mSerial; - } + if (ft->mSerial == object->mInventorySerialNum) + { + // Loop Protection. + // We received same serial twice. + // Viewer did some changes to inventory that couldn't be saved server side + // or something went wrong to cause serial to be out of sync + LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL; + object->mExpectedInventorySerialNum = ft->mSerial; + } - std::string unclean_filename; - msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename); - ft->mFilename = LLDir::getScrubbedFileName(unclean_filename); + if (ft->mSerial < object->mExpectedInventorySerialNum) + { + // out of date message, record to current serial for loop protection, but do not load it + // just drop xfer to restart on idle + if (ft->mSerial < object->mInventorySerialNum) + { + LL_WARNS() << "Somehow task serial decreased, out of order packet?" << LL_ENDL; + } + object->mInventorySerialNum = ft->mSerial; + object->mInvRequestXFerId = 0; + object->mInvRequestState = INVENTORY_REQUEST_STOPPED; + } + else if (ft->mSerial >= object->mExpectedInventorySerialNum) + { + object->mInventorySerialNum = ft->mSerial; + object->mExpectedInventorySerialNum = ft->mSerial; - if(ft->mFilename.empty()) - { - LL_DEBUGS() << "Task has no inventory" << LL_ENDL; - // mock up some inventory to make a drop target. - if(object->mInventory) - { - object->mInventory->clear(); // will deref and delete it - } - else - { - object->mInventory = new LLInventoryObject::object_list_t(); - } - LLPointer obj; - obj = new LLInventoryObject(object->mID, LLUUID::null, - LLAssetType::AT_CATEGORY, - "Contents"); - object->mInventory->push_front(obj); - object->doInventoryCallback(); - delete ft; - return; - } - U64 new_id = gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename), - ft->mFilename, LL_PATH_CACHE, - object->mRegionp->getHost(), - TRUE, - &LLViewerObject::processTaskInvFile, - (void**)ft, - LLXferManager::HIGH_PRIORITY); - if (object->mInvRequestState == INVENTORY_XFER) - { - if (new_id > 0 && new_id != object->mInvRequestXFerId) - { - // we started new download. - gXferManager->abortRequestById(object->mInvRequestXFerId, -1); - object->mInvRequestXFerId = new_id; - } - } - else - { - object->mInvRequestState = INVENTORY_XFER; - object->mInvRequestXFerId = new_id; - } + std::string unclean_filename; + msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename); + ft->mFilename = LLDir::getScrubbedFileName(unclean_filename); + + if (ft->mFilename.empty()) + { + LL_DEBUGS() << "Task has no inventory" << LL_ENDL; + // mock up some inventory to make a drop target. + if (object->mInventory) + { + object->mInventory->clear(); // will deref and delete it + } + else + { + object->mInventory = new LLInventoryObject::object_list_t(); + } + LLPointer obj; + obj = new LLInventoryObject(object->mID, LLUUID::null, + LLAssetType::AT_CATEGORY, + "Contents"); + object->mInventory->push_front(obj); + object->doInventoryCallback(); + delete ft; + return; + } + U64 new_id = gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename), + ft->mFilename, LL_PATH_CACHE, + object->mRegionp->getHost(), + TRUE, + &LLViewerObject::processTaskInvFile, + (void**)ft, + LLXferManager::HIGH_PRIORITY); + if (object->mInvRequestState == INVENTORY_XFER) + { + if (new_id > 0 && new_id != object->mInvRequestXFerId) + { + // we started new download. + gXferManager->abortRequestById(object->mInvRequestXFerId, -1); + object->mInvRequestXFerId = new_id; + } + } + else + { + object->mInvRequestState = INVENTORY_XFER; + object->mInvRequestXFerId = new_id; + } + } } void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status) @@ -3337,6 +3363,13 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS && ft->mSerial >= object->mInventorySerialNum) { object->mInventorySerialNum = ft->mSerial; + LL_DEBUGS() << "Receiving inventory task file for serial " << object->mInventorySerialNum << " taskid: " << ft->mTaskID << LL_ENDL; + if (ft->mSerial < object->mExpectedInventorySerialNum) + { + // User managed to change something while inventory was loading + LL_DEBUGS() << "Processing file that is potentially out of date for task: " << ft->mTaskID << LL_ENDL; + } + if (object->loadTaskInvFile(ft->mFilename)) { @@ -3498,7 +3531,7 @@ void LLViewerObject::removeInventory(const LLUUID& item_id) msg->addUUIDFast(_PREHASH_ItemID, item_id); msg->sendReliable(mRegionp->getHost()); deleteInventoryItem(item_id); - ++mInventorySerialNum; + ++mExpectedInventorySerialNum; } bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 0384b3e4fb..5fee3dcdf5 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -819,6 +819,7 @@ protected: typedef std::list callback_list_t; callback_list_t mInventoryCallbacks; S16 mInventorySerialNum; + S16 mExpectedInventorySerialNum; enum EInventoryRequestState { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 41ec0de381..ff5d0c4a17 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -79,6 +79,7 @@ #include "llselectmgr.h" #include "llsprite.h" #include "lltargetingmotion.h" +#include "lltoolmgr.h" #include "lltoolmorph.h" #include "llviewercamera.h" #include "llviewertexlayer.h" @@ -8076,12 +8077,33 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) gAgentCamera.changeCameraToMouselook(); } - //KC: revoke perms on sit + if (gAgentCamera.getFocusOnAvatar() && LLToolMgr::getInstance()->inEdit()) + { + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); + if (node && node->mValid) + { + LLViewerObject* root_object = node->getObject(); + if (root_object == sit_object) + { + LLFloaterTools::sPreviousFocusOnAvatar = true; + if (!gSavedSettings.getBOOL("EditCameraMovement")) + { + // always freeze camera in space, even if camera doesn't move + // so, for example, follow cam scripts can't affect you when in build mode + gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null); + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + } + } + } + } + + // revoke perms on sit U32 revoke_on = gSavedSettings.getU32("FSRevokePerms"); if ((revoke_on == 1 || revoke_on == 3) && !sit_object->permYouOwner()) { revokePermissionsOnObject(sit_object); } + // } if (mDrawable.isNull()) diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 4f8c541419..d689034f09 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3684,6 +3684,30 @@ You can either check your Internet connection and try again in a few minutes, cl + + fail +We're having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID]. + +You can either check your Internet connection and try again in a few minutes or click Help to view the [SUPPORT_SITE]. + + http://secondlife.com/support/ + +
+