diff options
Diffstat (limited to 'indra')
38 files changed, 421 insertions, 116 deletions
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 5d60c63810..62d97007ac 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -582,11 +582,12 @@ public: /// Generate a distinct name for a listener -- see listen() static std::string inventName(const std::string& pfx="listener"); -private: - friend class LLEventPumps; /// flush queued events virtual void flush() {} +private: + friend class LLEventPumps; + virtual void reset(); @@ -675,12 +676,14 @@ public: virtual ~LLEventMailDrop() {} /// Post an event to all listeners - virtual bool post(const LLSD& event); + virtual bool post(const LLSD& event) override; + /// Remove any history stored in the mail drop. + virtual void flush() override { mEventHistory.clear(); LLEventStream::flush(); }; protected: virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&, const NameList& after, - const NameList& before); + const NameList& before) override; private: typedef std::list<LLSD> EventList; @@ -703,7 +706,6 @@ public: /// Post an event to all listeners virtual bool post(const LLSD& event); -private: /// flush queued events virtual void flush(); diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp index 4c64f15ca7..1a4c6641b9 100644 --- a/indra/llcommon/tests/lluri_test.cpp +++ b/indra/llcommon/tests/lluri_test.cpp @@ -383,6 +383,41 @@ namespace tut ensure_equals("query", u.query(), "redirect-http-hack=secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak®ion=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78"); ensure_equals("query map element", u.queryMap()["redirect-http-hack"].asString(), "secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak®ion=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78"); } + + template<> template<> + void URITestObject::test<20>() + { + set_test_name("escapePathAndData uri test"); + + // Basics scheme:[//authority]path[?query][#fragment] + ensure_equals(LLURI::escapePathAndData("dirname?query"), + "dirname?query"); + ensure_equals(LLURI::escapePathAndData("dirname?query=data"), + "dirname?query=data"); + ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query#fragment"), + "host://dirname/subdir%20name?query#fragment"); + ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query=some@>data#fragment"), + "host://dirname/subdir%20name?query=some@%3Edata#fragment"); + ensure_equals(LLURI::escapePathAndData("host://dir[name/subdir name?query=some[data#fra[gment"), + "host://dir[name/subdir%20name?query=some%5Bdata#fra[gment"); + ensure_equals(LLURI::escapePathAndData("mailto:zero@ll.com"), + "mailto:zero@ll.com"); + // pre-escaped + ensure_equals(LLURI::escapePathAndData("host://dirname/subdir%20name"), + "host://dirname/subdir%20name"); + + // data:[<mediatype>][;base64],<data> + ensure_equals(LLURI::escapePathAndData("data:,Hello, World!"), + "data:,Hello%2C%20World%21"); + ensure_equals(LLURI::escapePathAndData("data:text/html,<h1>Hello, World!</h1>"), + "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E"); + // pre-escaped + ensure_equals(LLURI::escapePathAndData("data:text/html,%3Ch1%3EHello%2C%20World!</h1>"), + "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E"); + // assume that base64 does not need escaping + ensure_equals(LLURI::escapePathAndData("data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?="), + "data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?="); + } } diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index 867b2bb47b..90b7272efa 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -181,7 +181,7 @@ bool LLImageBMP::updateData() } } else - if( 12 <= header.mSize && 64 <= header.mSize ) + if( 12 <= header.mSize && header.mSize <= 64 ) { setLastError("OS/2 2.x BMP files are not supported"); return false; diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 280d2653d3..0e2f62f9db 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -401,7 +401,7 @@ public: child->insert(data); } } - else + else if (parent) { //it's not in here, give it to the root OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL; @@ -416,6 +416,13 @@ public: node->insert(data); } + else + { + // It's not in here, and we are root. + // LLOctreeRoot::insert() should have expanded + // root by now, something is wrong + OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL; + } return false; } @@ -763,10 +770,15 @@ public: { LLOctreeNode<T>::insert(data); } - else + else if (node->isInside(data->getPositionGroup())) { node->insert(data); } + else + { + // calling node->insert(data) will return us to root + OCT_ERRS << "Failed to insert data at child node" << LL_ENDL; + } } else if (this->getChildCount() == 0) { diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index e9d852c288..c41730ebaa 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -245,13 +245,11 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD) { mStyle |= LLFontGL::BOLD; - mStyle &= ~LLFontGL::NORMAL; } if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC) { mStyle |= LLFontGL::ITALIC; - mStyle &= ~LLFontGL::NORMAL; } return TRUE; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index b79615e730..86a4c35e6d 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -870,10 +870,6 @@ void LLFontGL::destroyAllGL() U8 LLFontGL::getStyleFromString(const std::string &style) { S32 ret = 0; - if (style.find("NORMAL") != style.npos) - { - ret |= NORMAL; - } if (style.find("BOLD") != style.npos) { ret |= BOLD; @@ -893,7 +889,7 @@ U8 LLFontGL::getStyleFromString(const std::string &style) std::string LLFontGL::getStringFromStyle(U8 style) { std::string style_string; - if (style & NORMAL) + if (style == NORMAL) { style_string += "|NORMAL"; } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index a1b31fd5cc..52190a1473 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -236,10 +236,14 @@ void LLUI::dirtyRect(LLRect rect) //static void LLUI::setMousePositionScreen(S32 x, S32 y) { - S32 screen_x, screen_y; - screen_x = ll_round((F32)x * getScaleFactor().mV[VX]); - screen_y = ll_round((F32)y * getScaleFactor().mV[VY]); - +#if defined(LL_DARWIN) + S32 screen_x = ll_round(((F32)x * getScaleFactor().mV[VX]) / LLView::getWindow()->getSystemUISize()); + S32 screen_y = ll_round(((F32)y * getScaleFactor().mV[VY]) / LLView::getWindow()->getSystemUISize()); +#else + S32 screen_x = ll_round((F32)x * getScaleFactor().mV[VX]); + S32 screen_y = ll_round((F32)y * getScaleFactor().mV[VY]); +#endif + LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert()); } diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 6dec131a34..3554f90be8 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -382,7 +382,10 @@ void callWindowFocus() void callWindowUnfocus() { - gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) + { + gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + } } void callWindowHide() diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index ca06394388..bee9433817 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.2.2 +6.2.3 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d0fbf17d81..be5611899a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3100,17 +3100,11 @@ LLSD LLAppViewer::getViewerInfo() const } // return a URL to the release notes for this viewer, such as: - // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456 + // https://releasenotes.secondlife.com/viewer/2.1.0.123456.html std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL"); if (! LLStringUtil::endsWith(url, "/")) url += "/"; - std::string channel = LLVersionInfo::getChannel(); - if (LLStringUtil::endsWith(boost::to_lower_copy(channel), " edu")) // Release Notes url shouldn't include the EDU parameter - { - boost::erase_tail(channel, 4); - } - url += LLURI::escape(channel) + "/"; - url += LLURI::escape(LLVersionInfo::getVersion()); + url += LLURI::escape(LLVersionInfo::getVersion()) + ".html"; info["VIEWER_RELEASE_NOTES_URL"] = url; diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 90a5483dc9..fe14bc081f 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -374,12 +374,40 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv) bool LLCommandLineParser::parseCommandLineString(const std::string& str) { + std::string cmd_line_string(""); + if (!str.empty()) + { + bool add_last_c = true; + S32 last_c_pos = str.size() - 1; //don't get out of bounds on pos+1, last char will be processed separately + for (S32 pos = 0; pos < last_c_pos; ++pos) + { + cmd_line_string.append(&str[pos], 1); + if (str[pos] == '\\') + { + cmd_line_string.append("\\", 1); + if (str[pos + 1] == '\\') + { + ++pos; + add_last_c = (pos != last_c_pos); + } + } + } + if (add_last_c) + { + cmd_line_string.append(&str[last_c_pos], 1); + if (str[last_c_pos] == '\\') + { + cmd_line_string.append("\\", 1); + } + } + } + // Split the string content into tokens - const char* escape_chars = "\\"; - const char* separator_chars = "\r\n "; - const char* quote_chars = "\"'"; + const char* escape_chars = "\\"; + const char* separator_chars = "\r\n "; + const char* quote_chars = "\"'"; boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars); - boost::tokenizer< boost::escaped_list_separator<char> > tok(str, sep); + boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep); std::vector<std::string> tokens; // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens)); for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin(); diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 0f02c23cb0..d24dac385f 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -566,27 +566,49 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV LLVector4a* normal, LLVector4a* tangent) { - LLViewerObject* hit = NULL; + if (!mRootVolp) + { + return NULL; + } - if (lineSegmentBoundingBox(start, end)) - { - LLVector4a local_end = end; - LLVector4a local_intersection; + LLViewerObject* hit = NULL; - if (mRootVolp && - mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent)) + if (lineSegmentBoundingBox(start, end)) + { + LLVector4a local_end = end; + LLVector4a local_intersection; + if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent)) { local_end = local_intersection; if (intersection) { *intersection = local_intersection; } - hit = mRootVolp; } - } - - return hit; + else + { + std::vector<LLVOVolume*> volumes; + getAnimatedVolumes(volumes); + + for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it) + { + LLVOVolume *volp = *vol_it; + if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent)) + { + local_end = local_intersection; + if (intersection) + { + *intersection = local_intersection; + } + hit = volp; + break; + } + } + } + } + + return hit; } // virtual diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index a9b15fc8b6..fea01786f3 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -1005,7 +1005,10 @@ F32 gpu_benchmark() //number of samples to take const S32 samples = 64; - + + //time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark. + const F32 time_limit = 30; + ShaderProfileHelper initProfile; std::vector<LLRenderTarget> dest(count); @@ -1023,12 +1026,14 @@ F32 gpu_benchmark() gGL.setColorMask(true, true); LLGLDepthTest depth(GL_FALSE); + LLTimer alloc_timer; + alloc_timer.start(); for (U32 i = 0; i < count; ++i) { //allocate render targets and textures if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true)) { - LL_WARNS() << "Failed to allocate render target." << LL_ENDL; + LL_WARNS("Benchmark") << "Failed to allocate render target." << LL_ENDL; // abandon the benchmark test delete[] pixels; return -1.f; @@ -1040,12 +1045,20 @@ F32 gpu_benchmark() if (!texHolder.bind(i)) { // can use a dummy value mDummyTexUnit = new LLTexUnit(-1); - LL_WARNS() << "Failed to bind tex unit." << LL_ENDL; + LL_WARNS("Benchmark") << "Failed to bind tex unit." << LL_ENDL; // abandon the benchmark test delete[] pixels; return -1.f; } LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + if (alloc_timer.getElapsedTimeF32() > time_limit) + { + // abandon the benchmark test + LL_WARNS("Benchmark") << "Allocation operation took longer then 30 seconds, stopping." << LL_ENDL; + delete[] pixels; + return -1.f; + } } delete [] pixels; @@ -1055,7 +1068,7 @@ F32 gpu_benchmark() if (!buff->allocateBuffer(3, 0, true)) { - LL_WARNS() << "Failed to allocate buffer during benchmark." << LL_ENDL; + LL_WARNS("Benchmark") << "Failed to allocate buffer during benchmark." << LL_ENDL; // abandon the benchmark test return -1.f; } @@ -1065,7 +1078,7 @@ F32 gpu_benchmark() if (! buff->getVertexStrider(v)) { - LL_WARNS() << "GL LLVertexBuffer::getVertexStrider() returned false, " + LL_WARNS("Benchmark") << "GL LLVertexBuffer::getVertexStrider() returned false, " << "buff->getMappedData() is" << (buff->getMappedData()? " not" : "") << " NULL" << LL_ENDL; @@ -1086,7 +1099,8 @@ F32 gpu_benchmark() buff->setBuffer(LLVertexBuffer::MAP_VERTEX); glFinish(); - for (S32 c = -1; c < samples; ++c) + F32 time_passed = 0; // seconds + for (S32 c = -1; c < samples && time_passed < time_limit; ++c) { LLTimer timer; timer.start(); @@ -1103,6 +1117,7 @@ F32 gpu_benchmark() glFinish(); F32 time = timer.getElapsedTimeF32(); + time_passed += time; if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow { @@ -1117,12 +1132,12 @@ F32 gpu_benchmark() F32 gbps = results[results.size()/2]; - LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers" << LL_ENDL; - + LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers, " << (F32)results.size() << " tests took " << time_passed << " seconds" << LL_ENDL; + #if LL_DARWIN if (gbps > 512.f) { - LL_WARNS() << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL; + LL_WARNS("Benchmark") << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL; //OSX is probably lying, discard result return -1.f; } @@ -1131,11 +1146,11 @@ F32 gpu_benchmark() F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f; F32 seconds = ms/1000.f; - F64 samples_drawn = res*res*count*samples; + F64 samples_drawn = res*res*count*results.size(); F32 samples_sec = (samples_drawn/1000000000.0)/seconds; gbps = samples_sec*8; - LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL; + LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL; return gbps; } diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 62e0e2d077..d7c5364fba 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -34,6 +34,7 @@ #include "llcachename.h" #include "llfloater.h" #include "llfloaterreg.h" +#include "llfloatersnapshot.h" // gSnapshotFloaterView #include "llinventory.h" #include "llscrolllistitem.h" #include "llscrolllistcell.h" @@ -236,24 +237,30 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) // Spawn at right side of cell LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small"); - LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 ); - - // Should we show a group or an avatar inspector? - bool is_group = hit_item->isGroup(); - bool is_experience = hit_item->isExperience(); - - LLToolTip::Params params; - params.background_visible( false ); - params.click_callback( boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience) ); - params.delay_time(0.0f); // spawn instantly on hover - params.image( icon ); - params.message(""); - params.padding(0); - params.pos(pos); - params.sticky_rect(sticky_rect); - - LLToolTipMgr::getInstance()->show(params); - handled = TRUE; + S32 screenX = sticky_rect.mRight - info_icon_size; + S32 screenY = sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight()) / 2; + LLCoordGL pos(screenX, screenY); + + LLFloater* snapshot_floatr = gSnapshotFloaterView->getFrontmostClosableFloater(); + if (!snapshot_floatr || !snapshot_floatr->getRect().pointInRect(screenX + icon->getWidth(), screenY)) + { + // Should we show a group or an avatar inspector? + bool is_group = hit_item->isGroup(); + bool is_experience = hit_item->isExperience(); + + LLToolTip::Params params; + params.background_visible(false); + params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience)); + params.delay_time(0.0f); // spawn instantly on hover + params.image(icon); + params.message(""); + params.padding(0); + params.pos(pos); + params.sticky_rect(sticky_rect); + + LLToolTipMgr::getInstance()->show(params); + handled = TRUE; + } } } } diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 52a13304df..0efb234015 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1962,6 +1962,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab() mRoleDescription(NULL), mMemberVisibleCheck(NULL), mDeleteRoleButton(NULL), + mCopyRoleButton(NULL), mCreateRoleButton(NULL), mFirstOpen(TRUE), mHasRoleChange(FALSE) @@ -2012,6 +2013,14 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) mCreateRoleButton->setClickedCallback(onCreateRole, this); mCreateRoleButton->setEnabled(FALSE); } + + mCopyRoleButton = + parent->getChild<LLButton>("role_copy", recurse); + if ( mCopyRoleButton ) + { + mCopyRoleButton->setClickedCallback(onCopyRole, this); + mCopyRoleButton->setEnabled(FALSE); + } mDeleteRoleButton = parent->getChild<LLButton>("role_delete", recurse); @@ -2226,6 +2235,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) mRoleTitle->clear(); setFooterEnabled(FALSE); mDeleteRoleButton->setEnabled(FALSE); + mCopyRoleButton->setEnabled(FALSE); } } @@ -2336,6 +2346,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect() mSelectedRole = item->getUUID(); buildMembersList(); + mCopyRoleButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE)); can_delete = can_delete && gAgent.hasPowerInGroup(mGroupID, GP_ROLE_DELETE); mDeleteRoleButton->setEnabled(can_delete); @@ -2662,6 +2673,57 @@ void LLPanelGroupRolesSubTab::handleCreateRole() } // static +void LLPanelGroupRolesSubTab::onCopyRole(void* user_data) +{ + LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data); + if (!self) return; + + self->handleCopyRole(); +} + +void LLPanelGroupRolesSubTab::handleCopyRole() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + + if (!gdatap) return; + + LLScrollListItem* role_item = mRolesList->getFirstSelected(); + if (!role_item || role_item->getUUID().isNull()) + { + return; + } + + LLRoleData rd; + if (!gdatap->getRoleData(role_item->getUUID(), rd)) + { + return; + } + + LLUUID new_role_id; + new_role_id.generate(); + rd.mRoleName += "(Copy)"; + gdatap->createRole(new_role_id,rd); + + mRolesList->deselectAllItems(TRUE); + LLSD row; + row["id"] = new_role_id; + row["columns"][0]["column"] = "name"; + row["columns"][0]["value"] = rd.mRoleName; + mRolesList->addElement(row, ADD_BOTTOM, this); + mRolesList->selectByID(new_role_id); + + // put focus on name field and select its contents + if(mRoleName) + { + mRoleName->setFocus(TRUE); + mRoleName->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + + notifyObservers(); +} + +// static void LLPanelGroupRolesSubTab::onDeleteRole(void* user_data) { LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data); diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index aafbd242cb..459b77703f 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -269,6 +269,9 @@ public: static void onCreateRole(void*); void handleCreateRole(); + static void onCopyRole(void*); + void handleCopyRole(); + static void onDeleteRole(void*); void handleDeleteRole(); @@ -296,6 +299,7 @@ protected: LLCheckBoxCtrl* mMemberVisibleCheck; LLButton* mDeleteRoleButton; LLButton* mCreateRoleButton; + LLButton* mCopyRoleButton; LLUUID mSelectedRole; BOOL mHasRoleChange; diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index f012d99adf..1533a27469 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -44,6 +44,7 @@ #include "roles_constants.h" #include "llscrollbar.h" #include "llselectmgr.h" +#include "lltrans.h" #include "llviewertexteditor.h" #include "llvfile.h" #include "llviewerinventory.h" @@ -767,7 +768,7 @@ void LLPreviewNotecard::openInExternalEditor() { if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error. { - msg = getString("external_editor_not_set"); + msg = LLTrans::getString("ExternalEditorNotSet"); } else { diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 76a21077ba..f1bb0bc27d 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1052,7 +1052,7 @@ void LLScriptEdCore::openInExternalEditor() { if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error. { - msg = getString("external_editor_not_set"); + msg = LLTrans::getString("ExternalEditorNotSet"); } else { diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 697db01d11..2a87bce134 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -113,19 +113,59 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) mMouseDownY = y; LLTimer pick_timer; BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); - mPick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged); - LLViewerObject *object = mPick.getObject(); - LLViewerObject *parent = object ? object->getRootEdit() : NULL; - if (!object - || object->isAttachment() - || object->getClickAction() == CLICK_ACTION_DISABLED - || (!useClickAction(mask, object, parent) && !object->flagHandleTouch() && !(parent && parent->flagHandleTouch()))) - { - // Unless we are hovering over actionable visible object - // left mouse down always picks transparent (but see handleMouseUp). - // Also see LLToolPie::handleHover() - priorities are a bit different there. - // Todo: we need a more consistent set of rules to work with - mPick = gViewerWindow->pickImmediate(x, y, TRUE /*transparent*/, pick_rigged); + LLPickInfo transparent_pick = gViewerWindow->pickImmediate(x, y, TRUE /*includes transparent*/, pick_rigged); + LLPickInfo visible_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged); + LLViewerObject *transp_object = transparent_pick.getObject(); + LLViewerObject *visible_object = visible_pick.getObject(); + + // Current set of priorities + // 1. Transparent attachment pick + // 2. Transparent actionable pick + // 3. Visible attachment pick (e.x we click on attachment under invisible floor) + // 4. Visible actionable pick + // 5. Transparent pick (e.x. movement on transparent object/floor, our default pick) + // left mouse down always picks transparent (but see handleMouseUp). + // Also see LLToolPie::handleHover() - priorities are a bit different there. + // Todo: we need a more consistent set of rules to work with + if (transp_object == visible_object || !visible_object) + { + // Note: if transparent object is null, then visible object is also null + // since transparent pick includes non-tranpsarent one. + // !transparent_object check will be covered by transparent_object == visible_object. + mPick = transparent_pick; + } + else + { + // Select between two non-null picks + LLViewerObject *transp_parent = transp_object->getRootEdit(); + LLViewerObject *visible_parent = visible_object->getRootEdit(); + if (transp_object->isAttachment()) + { + // 1. Transparent attachment + mPick = transparent_pick; + } + else if (transp_object->getClickAction() != CLICK_ACTION_DISABLED + && (useClickAction(mask, transp_object, transp_parent) || transp_object->flagHandleTouch() || (transp_parent && transp_parent->flagHandleTouch()))) + { + // 2. Transparent actionable pick + mPick = transparent_pick; + } + else if (visible_object->isAttachment()) + { + // 3. Visible attachment pick + mPick = visible_pick; + } + else if (visible_object->getClickAction() != CLICK_ACTION_DISABLED + && (useClickAction(mask, visible_object, visible_parent) || visible_object->flagHandleTouch() || (visible_parent && visible_parent->flagHandleTouch()))) + { + // 4. Visible actionable pick + mPick = visible_pick; + } + else + { + // 5. Default: transparent + mPick = transparent_pick; + } } LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL; diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 78268944fc..da31e4f542 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -47,6 +47,7 @@ // library includes #include "llnotificationsutil.h" #include "llsd.h" +#include "stringize.h" static LLURLDispatcherListener sURLDispatcherListener; @@ -255,14 +256,23 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL& // Teleportation links are handled here because they are tightly coupled // to SLURL parsing and sim-fragment parsing -class LLTeleportHandler : public LLCommandHandler +class LLTeleportHandler : public LLCommandHandler, public LLEventAPI { public: // Teleport requests *must* come from a trusted browser // inside the app, otherwise a malicious web page could // cause a constant teleport loop. JC - LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_THROTTLE) { } - + LLTeleportHandler() : + LLCommandHandler("teleport", UNTRUSTED_THROTTLE), + LLEventAPI("LLTeleportHandler", "Low-level teleport API") + { + LLEventAPI::add("teleport", + "Teleport to specified [\"regionname\"] at\n" + "specified region-relative [\"x\"], [\"y\"], [\"z\"].\n" + "If [\"regionname\"] omitted, teleport to GLOBAL\n" + "coordinates [\"x\"], [\"y\"], [\"z\"].", + &LLTeleportHandler::from_event); + } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) @@ -293,6 +303,41 @@ public: return true; } + void from_event(const LLSD& params) const + { + Response response(LLSD(), params); + if (params.has("regionname")) + { + // region specified, coordinates (if any) are region-local + LLVector3 local_pos( + params.has("x")? params["x"].asReal() : 128, + params.has("y")? params["y"].asReal() : 128, + params.has("z")? params["z"].asReal() : 0); + std::string regionname(params["regionname"]); + std::string destination(LLSLURL(regionname, local_pos).getSLURLString()); + // have to resolve region's global coordinates first + teleport_via_slapp(regionname, destination); + response["message"] = "Teleporting to " + destination; + } + else // no regionname + { + // coordinates are global, and at least (x, y) are required + if (! (params.has("x") && params.has("y"))) + { + return response.error("Specify either regionname or global (x, y)"); + } + LLVector3d global_pos(params["x"].asReal(), params["y"].asReal(), + params["z"].asReal()); + gAgent.teleportViaLocation(global_pos); + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if (instance) + { + instance->trackLocation(global_pos); + } + response["message"] = STRINGIZE("Teleporting to global " << global_pos); + } + } + static void teleport_via_slapp(std::string region_name, std::string callback_url) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2b9f0f642e..52b2c631fa 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4751,6 +4751,12 @@ void handle_take() category_id.setNull(); } + // check inbox + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); + if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id)) + { + category_id.setNull(); + } } } if(category_id.isNull()) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index ae4b065333..e10ba77e16 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1480,6 +1480,11 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) LLSD timeoutResult(LLSDMap("session", "timeout")); + // We are about to start a whole new session. Anything that MIGHT still be in our + // maildrop is going to be stale and cause us much wailing and gnashing of teeth. + // Just flush it all out and start new. + voicePump.flush(); + // It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4 // before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck. // For now, the SessionGroup.AddSession response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined. diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index c131cb886f..1e631a2272 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -630,7 +630,7 @@ void LLVOSky::initAtmospherics(void) dome_radius = LLWLParamManager::getInstance()->getDomeRadius(); dome_offset_ratio = LLWLParamManager::getInstance()->getDomeOffset(); sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error)); - ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error)); + ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getAmbient()); //lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error); gamma = LLWLParamManager::getInstance()->mCurParams.getFloat("gamma", error); blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error)); diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index 066cb9a0ac..cd7a32abdd 100644 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -284,6 +284,11 @@ void LLWLParamSet::setEastAngle(float val) mParamValues["east_angle"] = val; } +void LLWLParamSet::setAmbient(const LLVector4& val) +{ + set("ambient", val); +} + void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) { // set up the iterators @@ -379,6 +384,19 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle); setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle); + + // ambient + + LLVector4 srcAmbient = src.getAmbient(); + LLVector4 destAmbient = dest.getAmbient(); + LLVector4 rsltAmbient; + + for (int i = 0; i < LENGTHOFVECTOR4; ++i) + { + rsltAmbient.mV[i] = srcAmbient.mV[i] + ((destAmbient.mV[i] - srcAmbient.mV[i]) * weight); + } + + setAmbient(rsltAmbient); // now setup the sun properly diff --git a/indra/newview/llwlparamset.h b/indra/newview/llwlparamset.h index 6e5f1d3a4b..9874f0f2e0 100644 --- a/indra/newview/llwlparamset.h +++ b/indra/newview/llwlparamset.h @@ -136,6 +136,9 @@ public: void setEastAngle(F32 val); F32 getEastAngle(); + + void setAmbient(const LLVector4& val); + LLVector4 getAmbient(); @@ -207,6 +210,11 @@ inline F32 LLWLParamSet::getEastAngle() { return (F32) mParamValues["east_angle"].asReal(); } +inline LLVector4 LLWLParamSet::getAmbient() { + bool error; + return mParamValues.has("ambient") ? getVector("ambient", error) : LLVector4(0.5f, 0.75f, 1.0f, 1.19f); +} + inline void LLWLParamSet::setEnableCloudScrollX(bool val) { mParamValues["enable_cloud_scroll"][0] = val; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index b27257a262..a1a9643739 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -887,14 +887,9 @@ void LLWorldMapView::drawFrustum() F32 half_width_pixels = half_width_meters * meters_to_pixels; // Compute the frustum coordinates. Take the UI scale into account. -#if defined(LL_DARWIN) - F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor"); - F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * ui_scale_factor) * LLUI::getScaleFactor().mV[VX]; - F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * ui_scale_factor) * LLUI::getScaleFactor().mV[VY]; -#else F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]); F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]); -#endif + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 74d160dfae..eee3dc2c77 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -432,7 +432,7 @@ Prøv venligst om lidt igen. Noter om version </string> <string name="RELEASE_NOTES_BASE_URL"> - http://wiki.secondlife.com/wiki/Release_Notes/ + https://releasenotes.secondlife.com/viewer/ </string> <string name="LoadingData"> Henter... diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml index 57a48f7906..4dd64cba2a 100644 --- a/indra/newview/skins/default/xui/de/floater_about_land.xml +++ b/indra/newview/skins/default/xui/de/floater_about_land.xml @@ -370,8 +370,8 @@ Nur große Parzellen können in der Suche aufgeführt werden. <text name="landing_point"> Landepunkt: [LANDING] </text> - <button label="Festlegen" label_selected="Festlegen" left="234" name="Set" right="-88" tool_tip="Legt Ihren Standort als Landepunkt fest, an dem Besucher ankommen. Legt die Position Ihres Avatars innerhalb dieser Parzelle fest." width="70"/> - <button label="Löschen" label_selected="Löschen" left="312" name="Clear" tool_tip="Landepunkt löschen" width="70"/> + <button label="Festlegen" label_selected="Festlegen" name="Set" tool_tip="Legt Ihren Standort als Landepunkt fest, an dem Besucher ankommen. Legt die Position Ihres Avatars innerhalb dieser Parzelle fest." width="70"/> + <button label="Löschen" label_selected="Löschen" name="Clear" tool_tip="Landepunkt löschen" width="70"/> <text name="Teleport Routing: "> Teleport-Route: </text> @@ -442,7 +442,7 @@ Nur große Parzellen können in der Suche aufgeführt werden. <panel.string name="estate_override"> Eine oder mehrere dieser Optionen gelten auf Grundbesitzebene </panel.string> - <check_box label="Alle Besucher sind zugelassen (Bei Deaktivierung dieser Option werden Bannlinien generiert)" name="public_access"/> + <check_box label="Alle Besucher sind zugelassen" tool_tip="Bei Deaktivierung dieser Option werden Bannlinien generiert" name="public_access"/> <check_box label="Muss 18+ sein [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diese Parzelle betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/> <check_box label="Muss über Zahlungsinfo in Datei [ESTATE_PAYMENT_LIMIT] verfügen" name="limit_payment" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> <check_box label="Gruppe [GROUP] ohne Beschränkungen zulassen" name="GroupCheck" tool_tip="Gruppe im Register „Allgemein“ festlegen."/> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index db51e0a6e8..0fa4ec9aff 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -651,7 +651,7 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. Versionshinweise </string> <string name="RELEASE_NOTES_BASE_URL"> - http://wiki.secondlife.com/wiki/Release_Notes/ + https://releasenotes.secondlife.com/viewer/ </string> <string name="LoadingData"> Wird geladen... diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 51c7f62503..9f853fd960 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1916,6 +1916,7 @@ Only large parcels can be listed in search. layout="topleft" left="8" name="public_access" + tool_tip="" label="Anyone can visit (Unchecking this will create ban lines)" top_pad="10" width="278" /> diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 714d4166c0..f15f79e9aa 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -212,7 +212,15 @@ clicking on their names. layout="topleft" left="0" name="role_create" - width="120" /> + width="100" /> + <button + follows="top|left" + height="23" + label="Copy Role" + layout="topleft" + left_pad="10" + name="role_copy" + width="100" /> <button height="23" follows="top|left" @@ -220,7 +228,7 @@ clicking on their names. layout="topleft" left_pad="10" name="role_delete" - width="120" /> + width="100" /> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml index c56a5e17cd..ed37e9e2cc 100644 --- a/indra/newview/skins/default/xui/en/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml @@ -28,10 +28,6 @@ name="Title"> Script: [NAME] </panel.string> - <panel.string - name="external_editor_not_set"> - Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting. - </panel.string> <menu_bar bg_visible="false" follows="left|top" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 1e4ab75d66..8fa339a946 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -321,7 +321,7 @@ Please try logging in again in a minute.</string> <string name="ReleaseNotes">Release Notes</string> <!-- Always mark translate="false" for strings that are nothing but URLs, as they don't need translation. --> - <string name="RELEASE_NOTES_BASE_URL" translate="false">http://wiki.secondlife.com/wiki/Release_Notes/</string> + <string name="RELEASE_NOTES_BASE_URL" translate="false">https://releasenotes.secondlife.com/viewer/</string> <!-- Indicates something is being loaded. Maybe should be merged with RetrievingData --> <string name="LoadingData">Loading...</string> @@ -3936,7 +3936,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem <string name="EmptyOutfitText">There are no items in this outfit</string> <!-- External editor status codes --> - <string name="ExternalEditorNotSet">Select an editor using the ExternalEditor setting.</string> + <string name="ExternalEditorNotSet">Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.</string> <string name="ExternalEditorNotFound">Cannot find the external editor you specified. Try enclosing path to the editor with double quotes. (e.g. "/path to my/editor" "%s")</string> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 2b8d34859a..c9bfbd6610 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -643,7 +643,7 @@ Intenta iniciar sesión de nuevo en unos instantes. Notas de la versión </string> <string name="RELEASE_NOTES_BASE_URL"> - http://wiki.secondlife.com/wiki/Release_Notes/ + https://releasenotes.secondlife.com/viewer/ </string> <string name="LoadingData"> Cargando... diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index ab106a9ba8..959494545a 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -652,7 +652,7 @@ Veuillez réessayer de vous connecter dans une minute. Notes de version </string> <string name="RELEASE_NOTES_BASE_URL"> - http://wiki.secondlife.com/wiki/Release_Notes/ + https://releasenotes.secondlife.com/viewer/ </string> <string name="LoadingData"> Chargement... diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 948f5984df..9265ce9ec6 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -648,7 +648,7 @@ Prova ad accedere nuovamente tra un minuto. Note sulla versione </string> <string name="RELEASE_NOTES_BASE_URL"> - http://wiki.secondlife.com/wiki/Release_Notes/ + https://releasenotes.secondlife.com/viewer/ </string> <string name="LoadingData"> In caricamento... diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index 20dcedaa2a..1e123eb619 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -651,7 +651,7 @@ support@secondlife.com にお問い合わせください。 リリースノート </string> <string name="RELEASE_NOTES_BASE_URL"> - http://wiki.secondlife.com/wiki/Release_Notes/ + https://releasenotes.secondlife.com/viewer/ </string> <string name="LoadingData"> ローディング... diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index cd5639711f..cccc70a92a 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -608,7 +608,7 @@ Aguarde um minuto antes que tentar logar-se novamente. Notas de versão </string> <string name="RELEASE_NOTES_BASE_URL"> - http://wiki.secondlife.com/wiki/Release_Notes/ + https://releasenotes.secondlife.com/viewer/ </string> <string name="LoadingData"> Carregando... |