summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.hgtags559
-rw-r--r--[-rwxr-xr-x]BuildParams0
-rw-r--r--README.md48
-rw-r--r--autobuild.xml30
-rwxr-xr-xbuild.sh22
-rw-r--r--debian/changelog18
-rw-r--r--debian/compat1
-rw-r--r--debian/control16
-rw-r--r--debian/copyright32
-rw-r--r--debian/postinst43
-rw-r--r--debian/postrm41
-rw-r--r--debian/preinst39
-rw-r--r--debian/prerm42
-rw-r--r--debian/rules118
-rw-r--r--debian/source/lintian-overrides8
-rwxr-xr-xdoc/contributions.txt4
-rw-r--r--doc/sl-logo.pngbin0 -> 9630 bytes
-rw-r--r--indra/CMakeLists.txt53
-rw-r--r--indra/cmake/Copy3rdPartyLibs.cmake4
-rw-r--r--indra/cmake/LLAddBuildTest.cmake13
-rw-r--r--indra/cmake/Variables.cmake1
-rw-r--r--indra/cmake/bugsplat.cmake58
-rw-r--r--indra/linux_crash_logger/README.txt3
-rw-r--r--indra/llcommon/CMakeLists.txt11
-rw-r--r--indra/llcommon/llapp.cpp10
-rw-r--r--indra/llcommon/llapp.h4
-rw-r--r--indra/llcommon/llcoros.cpp76
-rw-r--r--indra/llcommon/llcoros.h7
-rw-r--r--indra/llcommon/llerror.cpp188
-rw-r--r--indra/llcommon/llerror.h60
-rw-r--r--indra/llcommon/llerrorcontrol.h57
-rw-r--r--indra/llcommon/llleap.cpp48
-rw-r--r--indra/llcommon/llregex.h89
-rw-r--r--indra/llcommon/llsingleton.cpp76
-rw-r--r--indra/llcommon/llsingleton.h86
-rw-r--r--indra/llcommon/llsys.cpp39
-rw-r--r--indra/llcommon/llthread.cpp3
-rw-r--r--indra/llcommon/lluri.cpp2
-rw-r--r--indra/llcommon/tests/llerror_test.cpp58
-rw-r--r--indra/llcommon/tests/wrapllerrs.h22
-rw-r--r--indra/llcorehttp/CMakeLists.txt1
-rw-r--r--indra/llcorehttp/_httpreplyqueue.cpp1
-rw-r--r--indra/llcorehttp/_httpreplyqueue.h1
-rw-r--r--indra/llcorehttp/_httprequestqueue.cpp12
-rw-r--r--indra/llcorehttp/_httprequestqueue.h2
-rw-r--r--indra/llcorehttp/_httpservice.cpp6
-rw-r--r--indra/llcorehttp/httpoptions.cpp11
-rw-r--r--indra/llcorehttp/httpoptions.h11
-rw-r--r--indra/llcrashlogger/README.txt3
-rw-r--r--indra/llcrashlogger/llcrashlogger.cpp1
-rw-r--r--indra/llimage/CMakeLists.txt1
-rw-r--r--indra/llimage/llimage.cpp7
-rw-r--r--indra/llinventory/lllandmark.cpp146
-rw-r--r--indra/llinventory/lllandmark.h2
-rw-r--r--indra/llinventory/llsettingsbase.cpp22
-rw-r--r--indra/llinventory/llsettingsbase.h20
-rw-r--r--indra/llinventory/llsettingsdaycycle.cpp28
-rw-r--r--indra/llinventory/llsettingssky.cpp128
-rw-r--r--indra/llinventory/llsettingswater.cpp22
-rw-r--r--indra/llmath/CMakeLists.txt1
-rw-r--r--indra/llmessage/llcoproceduremanager.cpp29
-rw-r--r--indra/llmessage/llcoproceduremanager.h4
-rw-r--r--indra/llmessage/llexperiencecache.cpp2
-rw-r--r--indra/llmessage/tests/llcoproceduremanager_test.cpp1
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp6
-rw-r--r--indra/llprimitive/llmediaentry.cpp5
-rw-r--r--indra/llrender/llrender.cpp1
-rw-r--r--indra/llrender/llrender.h1
-rw-r--r--indra/llrender/llrender2dutils.cpp23
-rw-r--r--indra/llrender/llrender2dutils.h13
-rw-r--r--indra/llui/llaccordionctrltab.cpp2
-rw-r--r--indra/llui/llconsole.cpp4
-rw-r--r--indra/llui/llfloater.cpp6
-rw-r--r--indra/llui/llfolderview.cpp9
-rw-r--r--indra/llui/llfolderviewitem.cpp13
-rw-r--r--indra/llui/llfolderviewitem.h2
-rw-r--r--indra/llui/llfolderviewmodel.cpp6
-rw-r--r--indra/llui/llmultislider.cpp23
-rw-r--r--indra/llui/llmultislider.h1
-rw-r--r--indra/llui/llnotificationptr.h3
-rw-r--r--indra/llui/llnotifications.h15
-rw-r--r--indra/llui/llscrolllistcolumn.cpp4
-rw-r--r--indra/llui/llscrolllistctrl.cpp4
-rw-r--r--indra/llui/lltoolbar.cpp2
-rw-r--r--indra/llui/lltooltip.cpp4
-rw-r--r--indra/llui/llui.cpp26
-rw-r--r--indra/llui/llui.h20
-rw-r--r--indra/llui/llurlentry.cpp11
-rw-r--r--indra/llui/llurlregistry.cpp12
-rw-r--r--indra/llui/llview.cpp22
-rw-r--r--indra/llui/llview.h3
-rw-r--r--indra/llui/tests/llurlentry_test.cpp5
-rw-r--r--indra/llvfs/lldir.cpp5
-rw-r--r--indra/llvfs/lldir.h1
-rw-r--r--indra/llvfs/lldiriterator.cpp4
-rw-r--r--indra/llwindow/llopenglview-objc.mm5
-rw-r--r--indra/llwindow/llwindowmacosx-objc.h2
-rw-r--r--indra/llwindow/llwindowmacosx.cpp11
-rw-r--r--indra/mac_crash_logger/README.txt3
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp53
-rw-r--r--indra/newview/CMakeLists.txt70
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml59
-rw-r--r--indra/newview/featuretable.txt11
-rw-r--r--indra/newview/featuretable_linux.txt11
-rw-r--r--indra/newview/featuretable_mac.txt11
-rw-r--r--indra/newview/llagent.cpp76
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/llappcorehttp.cpp58
-rw-r--r--indra/newview/llappcorehttp.h1
-rw-r--r--indra/newview/llappdelegate-objc.mm10
-rw-r--r--indra/newview/llappearancemgr.cpp88
-rw-r--r--indra/newview/llappviewer.cpp193
-rw-r--r--indra/newview/llappviewer.h5
-rw-r--r--indra/newview/llappviewermacosx.cpp62
-rw-r--r--indra/newview/llappviewerwin32.cpp73
-rw-r--r--indra/newview/llappviewerwin32.h22
-rw-r--r--indra/newview/llcompilequeue.cpp2
-rw-r--r--indra/newview/lldelayedgestureerror.cpp2
-rw-r--r--indra/newview/llenvironment.cpp118
-rw-r--r--indra/newview/llfloaterabout.cpp1
-rw-r--r--indra/newview/llfloaterbuyland.cpp3
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp2
-rw-r--r--indra/newview/llfloatereditenvironmentbase.cpp2
-rw-r--r--indra/newview/llfloaterexperienceprofile.cpp14
-rw-r--r--indra/newview/llfloaterexperienceprofile.h2
-rw-r--r--indra/newview/llfloatergridstatus.cpp1
-rw-r--r--indra/newview/llfloaterurlentry.cpp9
-rw-r--r--indra/newview/llfloaterurlentry.h1
-rw-r--r--indra/newview/llfloaterwindowsize.cpp6
-rw-r--r--indra/newview/llhudnametag.cpp11
-rw-r--r--indra/newview/llhudnametag.h4
-rw-r--r--indra/newview/llhudtext.cpp3
-rw-r--r--indra/newview/llimprocessing.cpp4
-rw-r--r--indra/newview/llinventorybridge.cpp9
-rw-r--r--indra/newview/llinventoryfilter.cpp5
-rw-r--r--indra/newview/llinventorymodel.cpp321
-rw-r--r--indra/newview/llinventorymodel.h4
-rw-r--r--indra/newview/llinventorypanel.cpp3
-rw-r--r--indra/newview/lllandmarklist.cpp114
-rw-r--r--indra/newview/lllandmarklist.h1
-rw-r--r--indra/newview/lllogchat.cpp12
-rw-r--r--indra/newview/llmediactrl.h3
-rw-r--r--indra/newview/llmeshrepository.cpp19
-rw-r--r--indra/newview/lloutfitgallery.cpp17
-rw-r--r--indra/newview/lloutfitslist.cpp5
-rw-r--r--indra/newview/llpanelexperiencepicker.cpp4
-rw-r--r--indra/newview/llpanellogin.cpp19
-rw-r--r--indra/newview/llpanellogin.h2
-rw-r--r--indra/newview/llpanelmaininventory.cpp39
-rw-r--r--indra/newview/llpanelmaininventory.h2
-rw-r--r--indra/newview/llpanelobject.cpp2
-rw-r--r--indra/newview/llpanelpicks.cpp45
-rw-r--r--indra/newview/llpanelpicks.h1
-rw-r--r--indra/newview/llpanelsnapshotpostcard.cpp3
-rw-r--r--indra/newview/llpreviewscript.cpp52
-rw-r--r--indra/newview/llpreviewscript.h2
-rw-r--r--indra/newview/llsecapi.h4
-rw-r--r--indra/newview/llsechandler_basic.cpp14
-rw-r--r--indra/newview/llsechandler_basic.h5
-rw-r--r--indra/newview/llselectmgr.cpp5
-rw-r--r--indra/newview/llskinningutil.cpp7
-rw-r--r--indra/newview/llstartup.cpp8
-rw-r--r--indra/newview/llteleporthistorystorage.cpp6
-rw-r--r--indra/newview/lltoolmgr.cpp2
-rw-r--r--indra/newview/lltoolpie.cpp40
-rw-r--r--indra/newview/lltranslate.cpp24
-rw-r--r--indra/newview/llversioninfo.cpp10
-rw-r--r--indra/newview/llviewerassetstorage.cpp4
-rw-r--r--indra/newview/llviewerassetupload.cpp2
-rw-r--r--indra/newview/llvieweraudio.cpp2
-rw-r--r--indra/newview/llvieweraudio.h5
-rw-r--r--indra/newview/llviewerdisplay.cpp33
-rw-r--r--indra/newview/llviewerfoldertype.cpp2
-rw-r--r--indra/newview/llviewermedia.cpp9
-rw-r--r--indra/newview/llviewermenu.cpp85
-rw-r--r--indra/newview/llviewerparcelmgr.cpp42
-rw-r--r--indra/newview/llviewerparcelmgr.h2
-rw-r--r--indra/newview/llviewerregion.cpp38
-rw-r--r--indra/newview/llviewerregion.h2
-rw-r--r--indra/newview/llviewerwindow.cpp5
-rw-r--r--indra/newview/llvoavatar.cpp27
-rw-r--r--indra/newview/llvocache.cpp125
-rw-r--r--indra/newview/llvocache.h2
-rw-r--r--indra/newview/llvoicevivox.cpp68
-rw-r--r--indra/newview/llvoicevivox.h1
-rw-r--r--indra/newview/llvovolume.cpp50
-rw-r--r--indra/newview/llwatchdog.cpp24
-rw-r--r--indra/newview/llwatchdog.h6
-rw-r--r--indra/newview/llweb.cpp9
-rw-r--r--indra/newview/llwebprofile.cpp1
-rw-r--r--indra/newview/llwlhandlers.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/floater_create_landmark.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml17
-rw-r--r--indra/newview/skins/default/xui/en/floater_url_entry.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml12
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml9
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml26
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_setup.xml45
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml6
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml2
-rw-r--r--indra/newview/tests/cppfeatures_test.cpp386
-rwxr-xr-xindra/newview/viewer_manifest.py19
-rw-r--r--indra/test/CMakeLists.txt6
-rw-r--r--indra/win_crash_logger/README.txt3
-rw-r--r--indra/win_crash_logger/llcrashloggerwindows.cpp2
-rwxr-xr-xscripts/metrics/viewerstats.py226
210 files changed, 3227 insertions, 2627 deletions
diff --git a/.hgtags b/.hgtags
deleted file mode 100755
index beb2da4191..0000000000
--- a/.hgtags
+++ /dev/null
@@ -1,559 +0,0 @@
-003dd9461bfa479049afcc34545ab3431b147c7c v2start
-52d96ad3d39be29147c5b2181b3bb46af6164f0e alpha-3
-d6781e22543acd7e21b967209f3c6e7003d380e3 fork to viewer-2-0
-7f16e79826d377f5f9f5b33dc721ab56d0d7dc8f alpha-4
-7f16e79826d377f5f9f5b33dc721ab56d0d7dc8f fork to viewer-20qa
-d40ac9dd949cba6dab1cc386da6a2027690c2519 alpha-5
-d2382d374139850efa5bb6adfb229e3e656cfc40 howard-demo
-b8419565906e4feb434426d8d9b17dd1458e24b2 alpha-6
-17fc2908e9a1ef34a9f53a41a393caf5c3cac390 beta-3-5
-3469d90a115b900f8f250e137bbd9b684130f5d2 beta-4
-12769e547e30067d494a6c01479a18107366ce2f beta-5
-4f777ffb99fefdc6497c61385c22688ff149c659 viewer-2-0-0
-668851b2ef0f8cf8df07a0fba429e4a6c1e70abb viewer-2-0-1
-08398e650c222336bb2b6de0cd3bba944aef11b4 2-1rn1
-80bc6cff515118a36108967af49d3f8105c95bc9 viewer-2-0-2-start
-46002088d9a4489e323b8d56131c680eaa21258c viewer-2-1-0-start
-3e4b947f79d88c385e8218cbc0731cef0e42cfc4 2-1-beta-1
-0962101bfa7df0643a6e625786025fe7f8a6dc97 2-1-beta-2
-1e2b517adc2ecb342cd3c865f2a6ccf82a3cf8d7 2-1-beta-3
-c6969fe44e58c542bfc6f1bd6c0be2fa860929ac 2-1-beta-4
-b03065d018b8a2e28b7de85b293a4c992cb4c12d 2-1-release
-19547b909b404552593be5ec7c18241e062a6d65 2-1-1-beta-1
-6e3b2e13906ba8ff22d3c8490b02d518adb2c907 2-1-1-beta-2
-bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2-1-1-release
-bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2.1.1-release
-c6e6324f5be1401f077ad18a4a0f6b46451c2f7b last_sprint
-7076e22f9f43f479a4ea75eac447a36364bead5a 2.2.0-beta1
-7076e22f9f43f479a4ea75eac447a36364bead5a DRTVWR-5_2.2.0-beta1
-7076e22f9f43f479a4ea75eac447a36364bead5a beta_2.1.3
-9822eb3e25f7fe0c28ffd8aba45c507caa383cbc 2.2.0-beta2
-9822eb3e25f7fe0c28ffd8aba45c507caa383cbc DRTVWR-3_2.2.0-beta2
-b0cd7e150009809a0b5b0a9d5785cd4bb230413a 2.2.0-beta3
-b0cd7e150009809a0b5b0a9d5785cd4bb230413a DRTVWR-7_2.2.0-beta3
-00a831292231faad7e44c69f76cb96f175b8dfad 2.2.0-beta4
-1415e6538d54fd5d568ee88343424d57c6803c2c 2.2.0-release
-1415e6538d54fd5d568ee88343424d57c6803c2c DRTVWR-8_2.2.0-release
-98e0d6df638429fd2f0476667504bd5a6b298def 2.3.0-start
-a3c12342b1af0951b8aa3b828aacef17fcea8178 2.3.0-beta1
-a3c12342b1af0951b8aa3b828aacef17fcea8178 DRTVWR-14_2.3.0-beta1
-db0fe9bb65187f365e58a717dd23d0f4754a9c1d 2.3.0-beta2
-db0fe9bb65187f365e58a717dd23d0f4754a9c1d DRTVWR-17_2.3.0-beta2
-6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 2.3.0-beta3
-6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 2.3.0-release
-6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 DRTVWR-13_2.3.0-release
-6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 DRTVWR-20_2.3.0-beta3
-dbc206fc61d89ff4cfe15aade0bf0c7bc7fee1c9 2.4.0-start
-3bc1f50a72e117f4d4ad8d555f0c785ea8cc201e 2.4.0-beta1
-3bc1f50a72e117f4d4ad8d555f0c785ea8cc201e DRTVWR-26_2.4.0-beta1
-25bd6007e3d2fc15db9326ed4b18a24a5969a46a 2.4.0-beta2
-25bd6007e3d2fc15db9326ed4b18a24a5969a46a DRTVWR-27_2.4.0-beta2
-1ed382c6a08ba3850b6ce9061bc551ddece0ea07 2.4.0-release
-1ed382c6a08ba3850b6ce9061bc551ddece0ea07 DRTVWR-25_2.4.0-release
-a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start
-345b17e7cf630db77e840b4fe3451bd476d750a3 2.5.0-beta1
-345b17e7cf630db77e840b4fe3451bd476d750a3 DRTVWR-32_2.5.0-beta1
-54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
-54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33--2.5.0beta2
-54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2
-b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
-b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
-b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
-b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
-b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
-63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
-4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
-4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
-b53a0576eec80614d7767ed72b40ed67aeff27c9 2.5.2-release
-b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
-4e9eec6a347f89b2b3f295beb72f1cf7837dff66 2.6.0-start
-9283d6d1d7eb71dfe4c330e7c9144857e7356bde 2.6.0-beta1
-9283d6d1d7eb71dfe4c330e7c9144857e7356bde DRTVWR-40_2.6.0-beta1
-461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip
-9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
-9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
-42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
-42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
-c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
-c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
-c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
-c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
-c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
-56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
-d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
-d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
-214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
-214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
-52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py
-ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start
-d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1
-d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
-0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2
-0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
-3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
-7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1
-7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
-800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start
-bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
-bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
-dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
-dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
-5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
-beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
-beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
-be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
-be2000b946f8cb3de5f44b2d419287d4c48ec4eb DRTVWR-54_2.6.8-release
-e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start
-77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-beta1
-77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-release
-77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-56_2.6.9-release
-77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-57_2.6.9-beta1
-8835e0e3c0d3a48244c287bc05811dfc2fba43ec 2.7.0-start
-43c7ee846b7eed80786acbbf35d03bd016a3e85d 2.7.0-beta1
-43c7ee846b7eed80786acbbf35d03bd016a3e85d DRTVWR-59_2.7.0-beta1
-54fd44ac92e4c61435ea33effe093a3527e18d98 2.7.1-start
-0c4d0c24278074f219e5a32e72b449e78301d11b 2.7.1-beta1
-0c4d0c24278074f219e5a32e72b449e78301d11b DRTVWR-61_2.7.1-beta1
-9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start
-e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
-e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
-fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
-fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
-fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
-fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
-6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
-6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
-be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1
-be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1
-057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
-057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
-19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start
-09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1
-09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1
-6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
-6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
-e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
-e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
-e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
-502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
-2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1
-2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1
-29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
-29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
-4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix
-4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix
-54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
-ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
-599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1
-599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1
-fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
-fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
-6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start
-b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
-b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
-1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
-1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
-82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start
-364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1
-364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
-f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start
-42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1
-42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
-e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2
-e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
-b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
-6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 3.0.3-beta1
-6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1
-61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2
-61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2
-0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release
-0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
-586907287be581817b2422b5137971b22d54ea48 3.0.4-start
-92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start
-c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start
-2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1
-2657fa785bbfac115852c41bd0adaff74c2ad5da DRTVWR-93_3.1.0-beta1
-bc01ee26fd0f1866e266429e85f76340523e91f1 3.1.0-beta2
-bc01ee26fd0f1866e266429e85f76340523e91f1 DRTVWR-96_3.1.0-beta2
-ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 3.1.0-release
-ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 DRTVWR-92_3.1.0-release
-a8230590e28e4f30f5105549e0e43211d9d55711 3.2.0-start
-e440cd1dfbd128d7d5467019e497f7f803640ad6 3.2.0-beta1
-e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
-9bcc2b7176634254e501e3fb4c5b56c1f637852e 3.2.0-beta2
-9bcc2b7176634254e501e3fb4c5b56c1f637852e DRTVWR-97_3.2.0-beta2
-2a13d30ee50ccfed50268238e36bb90d738ccc9e 3.2.0-beta3
-2a13d30ee50ccfed50268238e36bb90d738ccc9e DRTVWR-98_3.2.0-beta3
-3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
-3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
-c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
-9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
-9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
-a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
-a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
-40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
-523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
-523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
-80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
-3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
-3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
-3fe994349fae64fc40874bb59db387131eb35a41 DRTVWR-104_3.2.4-beta1
-bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
-bd6bcde2584491fd9228f1fa51c4575f4e764e19 DRTVWR-103_3.2.4-release
-8a44ff3d2104269ce76145c2772cf1bdff2a2abe 3.2.5-start
-3d2d5d244c6398a4214c666d5dd3965b0918709a 3.2.5-beta1
-3d2d5d244c6398a4214c666d5dd3965b0918709a DRTVWR-106_3.2.5-beta1
-65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d 3.2.5-beta2
-65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d DRTVWR-107_3.2.5-beta2
-c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
-c6175c955a19e9b9353d242889ec1779b5762522 DRTVWR-105_3.2.5-release
-2174ed1c7129562428a5cfe8651ed77b8d26ae18 3.2.6-start
-286d73ff5c19f6c00e023dc1b60975ed6bbe2872 3.2.6-beta1
-286d73ff5c19f6c00e023dc1b60975ed6bbe2872 DRTVWR-109_3.2.6-beta1
-4891c46a56fed7512c783b9cbe7cb7260727bf0c 3.2.7-start
-3d75c836d178c7c7e788f256afe195f6cab764a2 3.2.7-beta1
-3d75c836d178c7c7e788f256afe195f6cab764a2 DRTVWR-111_3.2.7-beta1
-89980333c99dbaf1787fe20784f1d8849e9b5d4f 3.2.8-start
-16f8e2915f3f2e4d732fb3125daf229cb0fd1875 3.2.8-beta1
-16f8e2915f3f2e4d732fb3125daf229cb0fd1875 DRTVWR-114_3.2.8-beta1
-987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
-987425b1acf4752379b2e1eb20944b4b35d67a85 DRTVWR-115_3.2.8-beta2
-51b2fd52e36aab8f670e0874e7e1472434ec4b4a 3.2.8-release
-51b2fd52e36aab8f670e0874e7e1472434ec4b4a DRTVWR-113_3.2.8-release
-37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
-e9c82fca5ae6fb8a8af29012d78fb194a29323f3 3.2.9-beta1
-e9c82fca5ae6fb8a8af29012d78fb194a29323f3 DRTVWR-117_3.2.9-beta1
-a01ef9bed28627f4ca543fbc1d70c79cc297a90f 3.2.9-beta2
-a01ef9bed28627f4ca543fbc1d70c79cc297a90f DRTVWR-118_3.2.9-beta2
-d5f263687f43f278107363365938f0a214920a4b 3.3.0-beta1
-d5f263687f43f278107363365938f0a214920a4b 3.3.0-start
-d5f263687f43f278107363365938f0a214920a4b DRTVWR-119
-5e8d2662f38a66eca6c591295f5880d47afc73f7 3.3.0-release
-3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 3.3.1-start
-3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 DRTVWR-125
-28b95a6a28dca3338d9a1f4f204b96678df9f6a5 3.3.1-beta1
-1dc545e44617975da2a4a32fe303386c687a6ca1 3.3.1-beta2
-1dc545e44617975da2a4a32fe303386c687a6ca1 DRTVWR-139
-1dc545e44617975da2a4a32fe303386c687a6ca1 viewer-beta-candidate
-c623bbc854b6f7ee1b33a3718f76715046aa2937 3.3.1-release
-d29a260119f8d5a5d168e25fed0c7ea6b3f40161 3.3.2-beta1
-675668bd24d3bea570814f71762a2a806f7e1b8d 3.3.2-beta2
-675668bd24d3bea570814f71762a2a806f7e1b8d 3.3.2-release
-15e90b52dc0297921b022b90d10d797436b8a1bd viewer-release-candidate
-bb9932a7a5fd00edf52d95f354e3b37ae6a942db DRTVWR-156
-6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148
-2a3965b3ad202df7ea25d2be689291bb14a1280e DRTVWR-155
-24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153
-5910f8063a7e1ddddf504c2f35ca831cc5e8f469 DRTVWR-160
-f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 3.3.3-beta1
-f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 DRTVWR-144
-2d6c0634b11e6f3df11002b8510a72a0433da00a DRTVWR-164
-600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
-80b5e5e9775966d3839331ffa7a16a60f9d7c930 DRTVWR-165
-fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2
-af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169
-4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3
-6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release
-a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
-9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
-089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
-c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
-b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171
-050e48759337249130f684b4a21080b683f61732 DRTVWR-168
-09ef7fd1b0781f33b8a3a9af6236b7bcb4831910 DRTVWR-170
-f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 DRTVWR-158
-f91d003091a61937a044652c4c674447f7dcbb7a 3.3.4-beta1
-bce218b2b45b730b22cc51e4807aa8b571cadef3 DRTVWR-173
-cbea6356ce9cb0c313b6777f10c5c14783264fcc DRTVWR-174
-82b5330bc8b17d0d4b598832e9c5a92e90075682 3.3.4-beta2
-57d221de3df94f90b55204313c2cef044a3c0ae2 DRTVWR-176
-eb539c65e6ee26eea2bf373af2d0f4b52dc91289 DRTVWR-177
-a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3
-4281aa899fb2cedb7a9ca7ce91c5c29d4aa69594 DRTVWR-180
-5c08e1d8edd871807153603b690e3ee9dbb548aa DRTVWR-183
-6c75f220b103db1420919c8b635fe53e2177f318 3.3.4-beta4
-9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184
-ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
-28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release
-6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
-7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
-8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
-351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
-005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
-888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
-a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182
-1f27cdfdc54246484f8afbbe42ce48e954175cbd 3.4.0-beta1
-9ee9387789701d597130f879d9011a4958753862 DRTVWR-189
-47f0d08ba7ade0a3905074009067c6d3df7e16ae DRTVWR-190
-421126293dcbde918e0da027ca0ab9deb5b4fbf2 DRTVWR-192
-33a2fc7a910ae29ff8b4850316ed7fbff9f64d33 DRTVWR-195
-e9732c739c8a72a590216951505ea9c76a526a84 DRTVWR-193
-7602f61c804a512764e349c034c02ddabeefebc4 DRTVWR-196
-ae5c83dd61d2d37c45f1d5b8bf2b036d87599f1b DRTVWR-198
-507bdfbd6bf844a511c1ffeda4baa80016ed1346 DRTVWR-197
-b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2
-37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200
-182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3
-7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201
-84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4
-573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5
-af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212
-015012c2b740ccdec8a8c3d6e5f898449ecfe0b8 DRTVWR-213
-62b07aa81b1957897c3846292bb9412977b0af6c 3.3.4-beta6
-ceed0b65a69f1eac20d523e0203320a32f9a3f3c DRTVWR-215
-733ceac77583874f3626ef7a15c105b83ef0f5bb 3.4.0-beta7
-97977c67245f52db20eb15f1918cc0f24778cabc 3.4.0-release
-5adb2b8f96c3cac88ad7c7d996d707f1b29df336 3.4.1-beta1
-b3f74858a1c8720c82d0978f3877a3fc8ba459ec 3.4.1-beta1a
-2b779f233ee6f38c89cb921650c773a96e63da92 DRTVWR-220
-0b9d95f4bfb6867cbf56eaec51633b0da2f1262d DRTVWR-221
-e6e553761829dc0270eaaa712b7cb0622535b076 3.4.1-beta3
-f00068a66a2e2f72acbe3f690b98b323e740b289 DRTVWR-222
-305950187c628a5d6743ee9ea711cc5b9177a18e 3.4.1-beta4
-dd23d4da3bcb2ffda58569e759feb7c119982973 DRTVWR-224
-0bd3744ff060452aa13ff4992eafb381df7b1012 3.4.1-beta5
-29075f8c1abed53dcf195a59f61744e27a91108f DRTVWR-226
-fba99f381b8d4ad1b7b42fa4993b29998d95be18 DRTVWR-179
-49ed253c80bed7410e238eeab35a9f14cb034364 3.4.1-beta6
-468ca3268229011a59df99229b24315844b33d34 DRTVWR-227
-524da902713e8b60322640b9825101add4a7c497 3.4.1-beta7
-173c2809f9873499c4b9d6bc044ec941c954d3fb DRTVWR-228
-1dc94555582f52718834081e7659e973ae4521f7 3.4.1-beta8
-52c164c8023a5e65f3dc1b0bbb7fa1dd0c631b6b DRTVWR-231
-464cf7a63a9a2f95bc4972dc022ca765e93de7d3 DRTVWR-233
-637fe8bbee5e24940448198c221d5ee0fa3247b4 3.4.1-beta9
-4e0d84e92132e9e95a1d52a1e49bad69c278ea05 3.4.1-beta10
-f7cbd60a3f57ff1101157eeb79ea21e8898bedae DRTVWR-235
-baf97f06ae17223614c5e31aa42e71d87cff07fe DRTVWR-236
-18498afcdb835d6fc4d36ed935347d3b65307bad 3.4.1-beta11
-b2f21e3442542283a80e7eaebae9f833e5a927b6 DRTVWR-237
-3f9be82de642d468c5fc272cb9d96b46b5498402 3.4.1-beta12
-e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release
-81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
-cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
-c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
-4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
-78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
-248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
-de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
-34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
-6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
-7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
-b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
-32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217
-704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1
-288539fc0408ed4b69a99665de33bbbc2c3c08fe DRTVWR-216
-e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2
-0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242
-710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3
-e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
-73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
-16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release
-d799593b53ed733862e9a13871e318e886469377 DRTVWR-208
-e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223
-93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240
-2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209
-f7bedce18ad52283e6072814db23318907261487 DRTVWR-238
-7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210
-5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241
-f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232
-4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245
-94ab2b49458ab372a95d2d6949fdf574f413068d 3.4.3-beta1
-965b9a35e260c0f53be1a25f0db7abc8a67eaf47 DRTVWR-252
-bb10adc4f76cf0067fca7075146f00cdc0740e9d DRTVWR-251
-ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253
-48382ec79741671d19ce4cc3e8cd59e9a521e4a7 DRTVWR-254
-937ec902bb9a1cbceff17bd89e3923352b0a5fbc DRTVWR-256
-44e764a6ac9e672a4f3bce821a4b6a218590c374 DRTVWR-258
-c23d734065ed593b2413385aecd8366d8e0ee96b DRTVWR-257
-452ce96d4046dc05a3ecaecc203e2cc8ddd72e76 DRTVWR-259
-daca610d840625b5bebb966a57cb49581852c417 DRTVWR-265
-9afbdc4e24cc04feacfb2b7a10b78a64f780901a DRTVWR-266
-73280db02501f5ad041fc18b1eba68e73a81996c DRTVWR-267
-870e2d79e0063fda87187f17bbc2747766733194 3.4.3-beta3
-0a2ca6546b499239afeb66d17b2fadbcdbe36ab1 3.4.3-release
-4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229
-f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246
-39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247
-7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249
-f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230
-b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255
-9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260
-84fbaf2d4141bd161731430e760949dc787ca206 DRTVWR-244
-083d2d36b5bb1c54fc3dd7caac0e7ac381a9cef0 3.4.4-beta1
-b634dec987c16e8c9c938e11e52591d9ead8fa9b DRTVWR-270
-cd39255bd23330fd30c04105f2811e941d8524fe 3.4.4-beta2
-2c4011bbc2b15b82198fd8b51f3a9fe765a08c4d DRTVWR-271
-2f8a3ef687bc55828abcb17ac1ad7cde70536d7e 3.4.4-beta3
-35cfd4cf5b895fa776592f2e630e330be7f0604e DRTVWR-273
-c374035d459af3c03dea2dd90880dfc25de64706 DRTVWR-275
-05d9f1dd7a954069af2a33abedb7713fa36a04cb 3.4.4-beta4
-e1bb1ae7d8b12faeb37933a737c199cc9b9f89cc 3.4.4-release
-391a8c74cec7275c5d26c85ad108d4782a3e3dd9 DRTVWR-268
-a36f1f354b02aa6e448ca13685de167d0a0a3d03 DRTVWR-272
-37dba00ad820de3a808d4039396b162a9c275b3e DRTVWR-269
-7c6dfdc1b7a2ce0d8e3a8f3ce3058547ea065c0f DRTVWR-250
-b9ff9730daa53a541925300cbd02bb14575a5705 DRTVWR-277
-af6b711a97073431953b55ee808aaa09900c27e5 DRTVWR-276
-8302fefde6c8f4a64bfc7f04929f8bc85f5c6c7b DRTVWR-279
-c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280
-40a2265058abc9fde4914c10185f916435818621 3.4.5-beta1
-5df4802bec93c8d0a509946d826bb4c50c5442ec DRTVWR-281
-7c1c33ba4cfd2d15ca51cc1ac440eca551331a4a DRTVWR-283
-6b9c7dbebef793230d64e1b452577c8b142d4143 3.4.5-beta2
-ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286
-2d849850558a5a0324b398d1c102d30bcbdfb88f DRTVWR-287
-e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3
-a676b4d6c037b39fe5b8e42cf8839a9303936089 DRTVWR-289
-28fa8b944a0c1869636ab00cc400f5aa71f6fa3c DRTVWR-290
-7f09bbc28c297f14b67961be7b6575445fa160e8 DRTVWR-291
-b23419a2748483c98f3b84b630468a21c88feba5 DRTVWR-292
-1567de5700c273b583dac41b64275c223287306e 3.4.5-beta4
-1cce8447f8f574673e3f47d6fe584262e6964fe2 DRTVWR-296
-0a5d409161ef2a89b28c9a741051dd2dedc707d6 DRTVWR-297
-852b69ef0b5fe6b13b69cc2217282cc64de6afab 3.4.5-beta5
-a49c715243a36a8a380504d14cb7416b3039c956 3.4.5-release
-37947e4f771f001b551581bf7cd0051c3153beed DRTVWR-282
-6482cceb91cda68b799f3e6cdc66d33bf123547a DRTVWR-284
-092a9effbedd1a0276fa5ced520992ce00f96fbf CHUI-PV-0
-279ef1dfc9b749a6cc499cf190fec0c090b6d682 DRTVWR-288
-9b19edaf1d8ddf435f60fbbb444dd25db8f63953 3.5.0-beta1
-c6b3561c7d7ad365eeba669db54eb57b5149ce75 3.5.0-beta2
-6d91ffd77bf2a20f18a2175eb7579da880ae12ac DRTVWR-302
-f6ca5bb75bca975ff0bc77e71e615f6478c4559c 3.5.0-beta3
-910b5fad950e343b58229f5a0aefa7729b9308b3 DRTVWR-303
-53cffdde0b3cc367ba9bb6abd5c83ae14df5e882 3.5.0-beta4
-4d5f6234dc59a0fb6ead5e02c7d343a0610e0488 DRTVWR-304
-dd058a6093c493120d67c8e02c812c0f7b2d3db0 3.5.0-beta5
-fd6b510e83f56830e45670c428653134899d3e25 DRTVWR-305
-55339537d99afc394d1bb7fdb7d074bf321ca62f 3.5.0-beta6
-902caf2b9fdbdbc5c399c4d5ebcecaf9cb97bab8 DRTVWR-306
-5c6098fd17d40ee3a38ca6b64f6be9db7f61f0a8 3.5.0-beta7
-adc360e6bf21390d2665380951d85937cd29a604 3.5.0-release
-1ada73295ed0eaa4a772ef079c29f57069342c32 DRTVWR-310
-20cdf370f5c8be6193bef6fb3a81cc3f81275191 3.5.1-beta1
-2319904200de367646b9a9442239a38d52c1eeb5 DRTVWR-313
-9d8726eca785acad694564516f16dd639faf45c0 3.5.1-beta2
-4b7fa963b80e2056ab648f83a4d61310b3cedb3d DRTVWR-314
-65ae89aeb7ea674a555e439e963f17949322ac94 3.5.1-beta3
-13149a524874b608aeb76325b35faff113a5ea53 3.5.1-release
-78a8fe6abf331944d6b6bb1ce1024a6bc08141f4 DRTVWR-298
-50ccc12f38c3c99f03b374e32429cb043b73e2a6 DRTVWR-294
-c2b1066514308dff1eeb91162392dfe08bf1c0fe DRTVWR-309
-e6b8a92acffd693cd1459e4212e3dff1050acf67 DRTVWR-278
-106f19cc011aafdfc9a6d12b641fe8db6e9735a7 3.5.2-beta1
-509b97acc4ca1f2644197f1b555773ac0bb6838c 3.5.2-beta2
-6cb3689d89c13876ce8fa8faefa7b05e4279502d DRTVWR-316
-cfc3e650e5b2063288e7b832e9c9f521bbdacc92 DRTVWR-315
-e6e35501f1fea252ef83080adcf30c3cb7c2f75c DRTVWR-299
-b6a4ac8f1916ede76e8a023e1cf35c045d0ac707 3.5.2-beta3
-a314f1c94374ab1f6633dd2983f7090a68663eb2 3.5.2-beta4
-1cfa86d604909dfdb8b372069ff61f9afaa2aac1 MAINT-2647
-895628bb5e162410cfdf4bca58f0a57d22ccfcde 3.5.2-beta5
-9013c07bfe1c51107233f1924dccdcc5057dd909 3.5.2-beta6
-9b1b6f33aa5394b27bb652b31b5cb81ef6060370 3.5.2-release
-a277b841729f2a62ba1e34acacc964bc13c1ad6f 3.5.3-release
-fb1630153bac5552046ea914af3f14deabc1def8 3.6.0-materials-beta1
-0a56f33ad6aa112032b14a41dad759ad377bdde9 3.6.0-release
-75cf8e855ae1af6895a35da475314c2b5acf1850 3.6.1-release
-f6741d5fe8d632651424484df0fe0cb4a01e9fbe 3.6.2-release
-fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
-83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
-91ed595b716f14f07409595b734fda891a59379e 3.6.4-release
-bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release
-ae457ece77001767ae9613148c495e7b98cc0f4a 3.6.7-release
-d40c66e410741de7e90b1ed6dac28dd8a2d7e1f6 3.6.8-release
-70eda3721d36df3e00730629c42a1304e5bc65b8 3.6.9-release
-5b54b36862ff8bc3b6935673c9d1c1f22ee8d521 3.6.10-release
-2feb70a4cfde43f2898d95ff8fcae3e67805c7c2 3.6.11-release
-88bbfd7a6971033f3aa103f3a3500ceb4c73521b 3.6.12-release
-0d9b9e50f1a8880e05f15688a9ec7d09e0e81013 3.6.13-release
-5d746de933a98ca17887cde2fece80e9c7ab0b98 3.7.0-release
-dcb4981ce255841b6083d8f65444b65d5a733a17 3.7.1-release
-b842534cb4d76c9ef87676a62b1d2d19e79c015f 3.7.2-release
-962d3f98955bfc7310a7867c8cbc3df075e54aa9 3.7.3-release
-d076568ff7883b41c149e6afb421f39c29dbfe2b 3.7.4-release
-fc066b82343fca51f9c1b8eda0abc6bee9bb4503 3.7.5-release
-d029faf69f20a23007f32420a1ac6a3b89a6d441 3.7.6-release
-83959480cb986522d07b151a0c778ab7f920d41b 3.7.7-release
-bba9b3722eea08949e4ff69591f736bf0f808434 3.7.8-release
-a9f2d0cb11f73b06858e6083bb50083becc3f9cd 3.7.9-release
-91dae9494b4d147541c7a01902334ba19a7ec05e 3.7.10-release
-64799eb298834073a3e9992cd8d27c3cb9d30b10 3.7.11-release
-3b44ea8988cb902f0dda8429e8d5e4569e304532 3.7.12-release
-d86a7e1bc96d27b683f951d3701d5b7042158c68 3.7.13-release
-a7872554f3665588f1e8347d472cec3a299254b3 3.7.14-release
-3f11f57f2b4d15a9f987d12bc70ef507eefb5018 3.7.15-release
-562e7dace7465060ac9adb2e8eca800b699ff024 3.7.16-release
-bcc2770e21c125e0bab59141c51db9145aec068d 3.7.17-release
-2729c1daf0257d68a40bdbc4acf1a16184974bbd 3.7.18-release
-82973b38a6c9a457333e3519e4f2b16bb5eedf47 3.7.19-release
-27094824773b907c2e559396e6f9ec3a963de52d 3.7.20-release
-9ecab4b0c7d8614767724a3422d3c1dca6bd4e4f 3.7.21-release
-bc61801f614022c920cb5c3df1d7d67a9561ce1f 3.7.22-release
-3be800e1afad9615442159e388d6d137be7b951e 3.7.23-release
-d3d0101e980ec95043e0af9b7903045d3bc447e4 3.7.24-release
-9978a8c3a2ffce4a5e1c186256581c2ac139c9dc 3.7.25-release
-000e9dda4162cbf0a83ba88558b19473654a09a9 3.7.26-release
-afd8d4756e8eda3c8f760625d1c17a2ad40ad6c8 3.7.27-release
-566874eb5ab26c003ef7fb0e22ce40c5fa0013f4 3.7.28-release
-d07f76c5b9860fb87924d00ca729f7d4532534d6 3.7.29-release
-67edc442c80b8d2fadd2a6c4a7184b469906cdbf 3.7.30-release
-797ed69e6134ef48bb922577ab2540fb2d964668 3.8.0-release
-3f61ed662347dc7c6941b8266e72746a66d90e2a 3.8.1-release
-3a62616f3dd8bd512fcdfd29ef033b2505b11213 3.8.2-release
-60572f718879f786f6bc8b5c9373ebebf4693078 3.8.3-release
-27e3cf444c4cc645884960a61325a9ee0e9a2d0f 3.8.4-release
-e821ef17c6edea4a59997719d8ba416d8c16e143 3.8.5-release
-5a5bd148943bfb46cf2ff2ccf376c42dee93d19b 3.8.6-release
-ae3297cdd03ab14f19f3811acbc4acd3eb600336 4.0.0-release
-759710a9acef61aaf7b69f4bc4a5a913de87ad8a 4.0.1-release
-e9d350764dfbf5a46229e627547ef5c1b1eeef00 4.0.2-release
-86dfba7ec4332c323025ebeacd8bf343ed0d8cfd 4.0.3-release
-0a5de9ec2cb868f367501024d8d6958c20869053 4.0.4-release
-450de775fff66a011be1a001acd117cc623c445d 4.0.5-release
-4070611edd95eb3a683d1cd97c4c07fe67793812 4.0.6-release
-33981d8130f031597b4c7f4c981b18359afb61a0 4.0.7-release
-45eaee56883df7a439ed3300c44d3126f7e3a41e 4.0.8-release
-b280a1c797a3891e68dbc237e73de9cf19f426e9 4.1.1-release
-bfbba2244320dc2ae47758cd7edd8fa3b67dc756 4.1.2-release
-b41e1e7c7876f7656c505f552b5888b4e478f92b 5.0.0-release
-c9ce2295012995e3cf5c57bcffcb4870b94c649f 5.0.1-release
-cea1632c002c065985ebea15eeeb4aac90f50545 5.0.2-release
-02c24e9f4f7d8aa0de75f27817dda098582f4936 5.0.3-release
-022709ef76a331cac1ba6ef1a6da8a5e9ef63f5a 5.0.4-release
-b4d76b5590fdf8bab72c64442353753a527cbc44 5.0.5-release
-3e5035dfd8af49bd4c0009f0a76ef46a15991a45 5.0.6-release
-abcab37e1b29414ab8c03af9ca2ab489d809788a 5.0.7-release
-505a492f30bd925bb48e2e093ae77c3c2b4c740f 5.0.8-release
-40ca7118765be85a043b31b011e4ee6bd9e33c95 5.0.9-release
-ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
-26d9e9bb166a9a417f35b1863223a597af8185fd 5.1.1-release
-2eb917875efdfe920680b9049302d0f03721245d 5.1.2-release
-7c00e5b6cb3d95712e9d8e29277c805bca2bda90 5.1.3-release
-7b6b020fd5ad9a8dc3670c5c92d1ca92e55fc485 5.1.4-release
-2ea47f358b171178eb9a95503a1670d519c2886f 5.1.5-release
-04538b8157c1f5cdacd9403f0a395452d4a93689 5.1.6-release
-ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
-23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release
-52422540bfe54b71155aa455360bee6e3ef1fd96 5.1.9-release
-1cfa567caf5088ae299271be08cc2d9f0801ff6a pre-Poseidon
-821edfcd14919c0e95c590866171c61fb57e8623 6.0.0-release
-21b7604680ef6b6ea67f8bebaaa588d6e263bdc1 6.0.1-release
-a3143db58a0f6b005232bf9018e7fef17ff9ec90 6.1.0-release
-50f0ece62ddb5a244ecb6d00ef5a89d80ad50efa 6.1.1-release
-82a89165e5929a6c3073d6cd60a543cb395f147b 6.2.0-release
-706bdc7e25c6e6b8fb56f4a13fcce2936e70a79c 6.2.1-release
-ec09daf1899c1c01c4ba0ba950fae572f2a612a8 6.2.2-release
-ab2ec5c5423b277d23fd0511ce50c15123ff2e03 6.2.3-release
-67297f9902857e357570c44722ad84de3aff974e 6.2.4-release
-9777aec6dc4a30a24537297ac040861ce16b82ae 6.3.0-release
-ece699718f163921717bb95a6131e94af4c4138f 6.3.1-release
-07f5d5bc9faebb45695853d40a9549773db816c0 6.3.2-release
-d9a4bd15e2c852953d6c8e84d6f3b7ca442c0e7f 6.3.3-release
-4033b3f57e76f087235145a3016886ccdc87ffa3 6.3.4-release
-27ca5834bfe9b80e82db5ea42f08b7eb990b722a 6.3.5-release
diff --git a/BuildParams b/BuildParams
index c5f96d5ee3..c5f96d5ee3 100755..100644
--- a/BuildParams
+++ b/BuildParams
diff --git a/README.md b/README.md
index e4078770f3..8813c25228 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,39 @@
-Second Life Viewer
-====================
-This project manages the source code for the
-[Second Life](https://www.secondlife.com) Viewer.
+![Second Life Logo](doc/sl-logo.png)
-This source is available as open source; for details on licensing, see
-[the licensing page on the Second Life wiki](https://wiki.secondlife.com/wiki/Linden_Lab_Official:Second_Life_Viewer_Licensing_Program)
+**[Second Life][] is a free 3D virtual world where users can create, connect and chat with others from around the
+world.** This repository contains the source code for the official client.
-For information on how to use and contribute to this, see
-[the open source portal on the wiki](https://wiki.secondlife.com/wiki/Open_Source_Portal).
+## Open Source
-To download the current default version, visit
-[the download page](https://secondlife.com/support/downloads). For
-even newer versions try
-[the Alternate Viewers page](https://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers)
+Second Life provides a huge variety of tools for expression, content creation, socialization and play. Its vibrancy is
+only possible because of input and contributions from its residents. The client codebase has been open source since
+2007 and is available under the LGPL license. The [Open Source Portal][] contains additional information about Linden
+Lab's open source history and projects.
+
+## Download
+
+Most people use a pre-built viewer release to access Second Life. Windows and macOS builds are
+[published on the official website][download]. More experimental viewers, such as release candidates and
+project viewers, are detailed on the [Alternate Viewers page](https://releasenotes.secondlife.com/viewer.html).
+
+### Third Party Viewers
+
+Third party maintained forks, which include Linux compatible builds, are indexed in the [Third Party Viewer Directory][tpv].
+
+## Build Instructions
+
+[Windows](https://wiki.secondlife.com/wiki/Build_the_Viewer_on_Windows)
+
+[Mac](https://wiki.secondlife.com/wiki/Build_the_Viewer_on_macOS)
+
+[Linux](https://wiki.secondlife.com/wiki/Build_the_Viewer_on_Linux)
+
+## Contribute
+
+Help make Second Life better! You can get involved with improvements by filing bugs, suggesting enhancements, submitting
+pull requests and more. See the [open source portal][] for details.
+
+[Second Life]: https://secondlife.com/
+[download]: https://secondlife.com/support/downloads/
+[tpv]: http://wiki.secondlife.com/wiki/Third_Party_Viewer_Directory
+[open source portal]: http://wiki.secondlife.com/wiki/Open_Source_Portal
diff --git a/autobuild.xml b/autobuild.xml
index 718234688b..e79e743de3 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -580,9 +580,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>856ba0e5b7be4bf683cf2849bce845e0</string>
+ <string>49fff41e17e06cdf9eb0c737d20df52f</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72458/699860/dullahan-1.7.0.202011160759_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-552313.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83411/779825/dullahan-1.12.2.202106220202_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-560751.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -592,9 +592,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>515950c911a53ff910b18c7c417ea984</string>
+ <string>f51f324d50a2461cda273e84fa65e0ad</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72460/699870/dullahan-1.7.0.202011161603_81.3.10_gb223419_chromium-81.0.4044.138-windows-552313.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83413/779836/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-560751.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -604,16 +604,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>f1dccbdfe0603f488eeee4c8f518c959</string>
+ <string>d3df46f6592715c75df2bf520c1ad68b</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72459/699874/dullahan-1.7.0.202011161603_81.3.10_gb223419_chromium-81.0.4044.138-windows64-552313.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/83412/779840/dullahan-1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-560751.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>1.7.0.202011161603_81.3.10_gb223419_chromium-81.0.4044.138</string>
+ <string>1.12.2.202106220213_91.1.21_g9dd45fe_chromium-91.0.4472.114</string>
</map>
<key>elfio</key>
<map>
@@ -2187,18 +2187,18 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>40a87f5d505a141b2ec79513a6197c35</string>
+ <string>0a6349b11c8e9d34f0c80b8081736e75</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76516/728250/llca-202102021657.555615-common-555615.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/79438/751815/llca-202104010215.557744-common-557744.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
- <string>202102021657.555615</string>
+ <string>202104010215.557744</string>
</map>
<key>llphysicsextensions_source</key>
<map>
@@ -3206,9 +3206,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>6989053898b8e81e904e75553e378820</string>
+ <string>97fac6d88480445c856083ed20d78093</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77523/735051/viewer_manager-2.0.556340-darwin64-556340.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85206/790666/viewer_manager-2.0.562101-darwin64-562101.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -3230,9 +3230,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>3446c1e54bb32542677caad0ec0d42ac</string>
+ <string>3f6271ec0e2e2f0cc1067d4c4102bb4c</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77525/735058/viewer_manager-2.0.556340-windows-556340.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/85208/790681/viewer_manager-2.0.562101-windows-562101.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -3243,7 +3243,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
- <string>2.0.556340</string>
+ <string>2.0.562101</string>
</map>
<key>vlc-bin</key>
<map>
diff --git a/build.sh b/build.sh
index 3b0cf97731..96bcff0e8e 100755
--- a/build.sh
+++ b/build.sh
@@ -129,11 +129,6 @@ pre_build()
then # show that we're doing this, just not the contents
echo source "$bugsplat_sh"
source "$bugsplat_sh"
- # important: we test this and use its value in [grand-]child processes
- if [ -n "${BUGSPLAT_DB:-}" ]
- then echo export BUGSPLAT_DB
- export BUGSPLAT_DB
- fi
fi
set -x
@@ -429,6 +424,15 @@ then
fi
fi
+# Some of the uploads takes a long time to finish in the codeticket backend,
+# causing the next codeticket upload attempt to fail.
+# Inserting this after each potentially large upload may prevent those errors.
+# JJ is making changes to Codeticket that we hope will eliminate this failure, then this can be removed
+wait_for_codeticket()
+{
+ sleep $(( 60 * 6 ))
+}
+
# check status and upload results to S3
if $succeeded
then
@@ -445,6 +449,7 @@ then
# Upload base package.
python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \
|| fatal "Upload of installer failed"
+ wait_for_codeticket
# Upload additional packages.
for package_id in $additional_packages
@@ -454,6 +459,7 @@ then
then
python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \
|| fatal "Upload of installer $package_id failed"
+ wait_for_codeticket
else
record_failure "Failed to find additional package for '$package_id'."
fi
@@ -467,6 +473,7 @@ then
# Upload crash reporter file
python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
|| fatal "Upload of symbolfile failed"
+ wait_for_codeticket
fi
# Upload the llphysicsextensions_tpv package, if one was produced
@@ -474,6 +481,9 @@ then
if [ -r "$build_dir/llphysicsextensions_package" ]
then
llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
+ # This next upload is a frequent failure; see if giving the last one some time helps
+ # JJ is making changes to Codeticket that we hope will eliminate this failure soon
+ sleep 300
python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \
|| fatal "Upload of physics extensions package failed"
fi
@@ -486,6 +496,7 @@ then
begin_section "Upload Extension $extension"
. $extension
[ $? -eq 0 ] || fatal "Upload of extension $extension failed"
+ wait_for_codeticket
end_section "Upload Extension $extension"
done
fi
@@ -495,7 +506,6 @@ then
record_event "skipping upload of installer"
fi
-
else
record_event "skipping upload of installer due to failed build"
fi
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index ce54b54c6f..0000000000
--- a/debian/changelog
+++ /dev/null
@@ -1,18 +0,0 @@
-secondlife-viewer (0.3) unstable; urgency=low
-
- * Initial debian configuration
-
- -- Don Kjer <don@lindenlab.com> Wed, 04 Jul 2012 00:43:03 +0000
-
-secondlife-viewer (0.2) unstable; urgency=low
-
- * Adding default LSB headers for squeeze
-
- -- Tyler Kohler <tyler@lindenlab.com> Thu, 24 Mar 2011 09:43:36 -0700
-
-secondlife-viewer (0.1) unstable; urgency=low
-
- * Cloned from debian package skeleton.
-
- -- Lex Linden <lex@lindenlab.com> Mon, 20 Sep 2010 08:01:59 -0700
-
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index 7ed6ff82de..0000000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-5
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 50b9ed9a26..0000000000
--- a/debian/control
+++ /dev/null
@@ -1,16 +0,0 @@
-Source: secondlife-viewer
-Section: unknown
-Priority: extra
-Maintainer: Don Linden <don@lindenlab.com>
-Build-Depends: debhelper (>= 5)
-Homepage: http://secondlife.com
-Standards-Version: 3.7.2
-
-Package: secondlife-viewer
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends},
- ia32-libs,
- ia32-libs-gtk
-Description: Second Life Viewer
- Second Life is an online virtual world developed by Linden Lab.
-
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 106fa3802f..0000000000
--- a/debian/copyright
+++ /dev/null
@@ -1,32 +0,0 @@
-Second Life Viewer Copyright: 2000-2012 Linden Research, Inc.
-
-License:
-
-3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
-APR Copyright (C) 2011 The Apache Software Foundation
-Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
-cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
-DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
-expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
-FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
-GL Copyright (C) 1999-2004 Brian Paul.
-GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
-google-perftools Copyright (c) 2005, Google Inc.
-Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
-jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
-jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
-ogg/vorbis Copyright (C) 2002, Xiphophorus
-OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
-PCRE Copyright (c) 1997-2012 University of Cambridge
-SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
-SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
-zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
-
-Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details.
-
-This software contains source code provided by NVIDIA Corporation.
-
-All rights reserved. See licenses.txt for details.
-
-Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
diff --git a/debian/postinst b/debian/postinst
deleted file mode 100644
index 2c4f8ea858..0000000000
--- a/debian/postinst
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-# postinst script for secondlife-viewer
-#
-# Delete this file if you don't need it.
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-# * <postinst> `configure' <most-recently-configured-version>
-# * <old-postinst> `abort-upgrade' <new version>
-# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
-# <new-version>
-# * <postinst> `abort-remove'
-# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
-# <failed-install-package> <version> `removing'
-# <conflicting-package> <version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
- configure)
- ;;
-
- abort-upgrade|abort-remove|abort-deconfigure)
- ;;
-
- *)
- echo "postinst called with unknown argument \`$1'" >&2
- exit 1
- ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts. Don't delete this!
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/postrm b/debian/postrm
deleted file mode 100644
index a575936ab0..0000000000
--- a/debian/postrm
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-# postrm script for secondlife-viewer
-#
-# Delete this file if you don't need it.
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-# * <postrm> `remove'
-# * <postrm> `purge'
-# * <old-postrm> `upgrade' <new-version>
-# * <new-postrm> `failed-upgrade' <old-version>
-# * <new-postrm> `abort-install'
-# * <new-postrm> `abort-install' <old-version>
-# * <new-postrm> `abort-upgrade' <old-version>
-# * <disappearer's-postrm> `disappear' <overwriter>
-# <overwriter-version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
- purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
- ;;
-
- *)
- echo "postrm called with unknown argument \`$1'" >&2
- exit 1
- ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts. Don't delete this!
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/preinst b/debian/preinst
deleted file mode 100644
index f62243440f..0000000000
--- a/debian/preinst
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-# preinst script for secondlife-viewer
-#
-# Delete this file if you don't need it.
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-# * <new-preinst> `install'
-# * <new-preinst> `install' <old-version>
-# * <new-preinst> `upgrade' <old-version>
-# * <old-preinst> `abort-upgrade' <new-version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
- install|upgrade)
- ;;
-
- abort-upgrade)
- ;;
-
- *)
- echo "preinst called with unknown argument \`$1'" >&2
- exit 1
- ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts. Don't delete this!
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/prerm b/debian/prerm
deleted file mode 100644
index 405b8f9c87..0000000000
--- a/debian/prerm
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-# prerm script for secondlife-viewer
-#
-# Delete this file if you don't need it.
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-# * <prerm> `remove'
-# * <old-prerm> `upgrade' <new-version>
-# * <new-prerm> `failed-upgrade' <old-version>
-# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
-# * <deconfigured's-prerm> `deconfigure' `in-favour'
-# <package-being-installed> <version> `removing'
-# <conflicting-package> <version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
- remove|upgrade|deconfigure)
- ;;
-
- failed-upgrade)
- ;;
-
- *)
- echo "prerm called with unknown argument \`$1'" >&2
- exit 1
- ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts. Don't delete this!
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/rules b/debian/rules
deleted file mode 100644
index 305fc58bb4..0000000000
--- a/debian/rules
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-# Sample debian/rules that uses debhelper.
-# This file was originally written by Joey Hess and Craig Small.
-# As a special exception, when this file is copied by dh-make into a
-# dh-make output file, you may use that output file without restriction.
-# This special exception was added by Craig Small in version 0.37 of dh-make.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-BASEDIR=opt/linden
-
-VIEWER_PKG=secondlife-viewer
-VIEWER_PACKAGEDIR=build-linux-i686/newview/packaged
-VIEWER_DESTDIR=$(CURDIR)/debian/$(VIEWER_PKG)
-VIEWER_VERSION:=$(shell dpkg-parsechangelog | grep ^Version | sed 's/^Version: //')
-VIEWER_INSTALLDIR:=$(BASEDIR)/viewer/SecondLife-i686-$(VIEWER_VERSION)
-
-configure: configure-stamp
-configure-stamp:
- dh_testdir
- # Add here commands to configure the package.
-
- touch configure-stamp
-
-build: build-stamp
-
-build-stamp: configure-stamp
- dh_testdir
-
- # Add here commands to compile the package.
- #$(MAKE)
- #docbook-to-man debian/secondlife-viewer.sgml > secondlife-viewer.1
-
- touch $@
-
-clean:
- dh_testdir
- dh_testroot
- rm -f build-stamp configure-stamp
-
- # Add here commands to clean up after the build process.
- #-$(MAKE) clean
-
- dh_clean
-
-install: build
- dh_testdir
- dh_testroot
- dh_clean -k
- dh_installdirs
-
- # Add here commands to install the package into debian/secondlife-viewer.
- for file in $$(find $(VIEWER_PACKAGEDIR) -type f -o -type l | sed 's~$(VIEWER_PACKAGEDIR)/~~'); do \
- # create containing directory \
- install -v -m 755 -o root -g root -d "$$(dirname "$(VIEWER_DESTDIR)/$(VIEWER_INSTALLDIR)/$$file")"; \
- PERM=644; \
- if [ -x "$(VIEWER_PACKAGEDIR)/$$file" ]; then \
- PERM=755; \
- fi; \
- if [ -L "$(VIEWER_PACKAGEDIR)/$$file" ]; then \
- REAL="$$( readlink -f $(VIEWER_PACKAGEDIR)/$$file )"; \
- RELATIVE="$$( echo $$REAL | sed 's~$(CURDIR)/$(VIEWER_PACKAGEDIR)/~~' )"; \
- echo dh_link -p $(VIEWER_PKG) "$(VIEWER_INSTALLDIR)/$$RELATIVE" "$(VIEWER_INSTALLDIR)/$$file" ; \
- dh_link -p $(VIEWER_PKG) "$(VIEWER_INSTALLDIR)/$$RELATIVE" "$(VIEWER_INSTALLDIR)/$$file" ; \
- else \
- install -v -m $$PERM -o root -g root "$(VIEWER_PACKAGEDIR)/$$file" "$(VIEWER_DESTDIR)/$(VIEWER_INSTALLDIR)/$$file"; \
- fi; \
- done
- dh_link -p $(VIEWER_PKG) /$(VIEWER_INSTALLDIR)/secondlife /usr/bin/secondlife
- dh_link -p $(VIEWER_PKG) $(BASEDIR)/viewer/SecondLife-i686-$(VIEWER_VERSION) $(BASEDIR)/viewer/SecondLife
-
-
-# Build architecture-independent files here.
-binary-indep: build install
-# We have nothing to do by default.
-
-# Build architecture-dependent files here.
-binary-arch: build install
- dh_testdir
- dh_testroot
- dh_installchangelogs
- dh_installdocs
- dh_installexamples
-# dh_install
-# dh_installmenu
-# dh_installdebconf
-# dh_installlogrotate
-# dh_installemacsen
-# dh_installpam
-# dh_installmime
-# dh_python
-
-# To add an init script, uncomment this line and edit debian/init.d and
-# customize debian/secondlife-viewer.default to suit your needs.
-# dh_installinit
-
-# To add cron jobs, uncomment this line and make a crontab file named
-# debian/cron.d, and it will be installed in /etc/cron.d/
-# dh_installcron
-
-# dh_installinfo
- dh_installman
- dh_link
-# dh_strip
- dh_compress
-# dh_fixperms
-# dh_perl
-# dh_makeshlibs
- dh_installdeb
-# dh_shlibdeps
- dh_gencontrol
- dh_md5sums
- dh_builddeb
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
deleted file mode 100644
index 661c20b572..0000000000
--- a/debian/source/lintian-overrides
+++ /dev/null
@@ -1,8 +0,0 @@
-# Linden packages install in opt/linden
-secondlife-viewer: dir-or-file-in-opt
-secondlife-viewer: section-is-dh_make-template
-secondlife-viewer: binary-without-manpage
-secondlife-viewer: maintainer-script-empty postrm
-secondlife-viewer: maintainer-script-empty preinst
-secondlife-viewer: maintainer-script-empty prerm
-secondlife-viewer: unstripped-binary-or-object
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 8ae828e738..308876a415 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -226,6 +226,7 @@ Ansariel Hiller
SL-13364
SL-13858
SL-13697
+ SL-13395
SL-3136
Aralara Rajal
Arare Chantilly
@@ -268,6 +269,8 @@ Beq Janus
SL-11300
SL-13583
SL-14766
+ SL-14927
+ SL-11300
Beth Walcher
Bezilon Kasei
Biancaluce Robbiani
@@ -804,6 +807,7 @@ Jonathan Yap
STORM-2104
STORM-2142
SL-10089
+ BUG-229818
Kadah Coba
STORM-1060
STORM-1843
diff --git a/doc/sl-logo.png b/doc/sl-logo.png
new file mode 100644
index 0000000000..b9563c7ac7
--- /dev/null
+++ b/doc/sl-logo.png
Binary files differ
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 53e5d7b6a5..db88e44127 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -13,6 +13,7 @@ project(${ROOT_PROJECT_NAME})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(Variables)
+include(bugsplat)
include(BuildVersion)
set(LEGACY_STDIO_LIBS)
@@ -50,7 +51,10 @@ endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
add_custom_target(viewer)
+if (NOT USE_BUGSPLAT)
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
+endif (NOT USE_BUGSPLAT)
+
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
@@ -64,29 +68,18 @@ add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
endif (ENABLE_MEDIA_PLUGINS)
if (LINUX)
- add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
if (INSTALL_PROPRIETARY)
include(LLAppearanceUtility)
add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
endif (INSTALL_PROPRIETARY)
- add_dependencies(viewer linux-crash-logger-strip-target)
-elseif (DARWIN)
- add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
- add_dependencies(viewer mac-crash-logger)
-elseif (WINDOWS)
- add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
- # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
- if (EXISTS ${VIEWER_DIR}win_setup)
- add_subdirectory(${VIEWER_DIR}win_setup)
- endif (EXISTS ${VIEWER_DIR}win_setup)
- # add_dependencies(viewer windows-setup windows-crash-logger)
- add_dependencies(viewer windows-crash-logger)
endif (LINUX)
-add_subdirectory(${VIEWER_PREFIX}newview)
-add_dependencies(viewer secondlife-bin)
-
-add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
+if (WINDOWS)
+ # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
+ if (EXISTS ${VIEWER_DIR}win_setup)
+ add_subdirectory(${VIEWER_DIR}win_setup)
+ endif (EXISTS ${VIEWER_DIR}win_setup)
+endif (WINDOWS)
# sets the 'startup project' for debugging from visual studio.
set_property(
@@ -94,6 +87,32 @@ set_property(
PROPERTY VS_STARTUP_PROJECT secondlife-bin
)
+if (USE_BUGSPLAT)
+ if (BUGSPLAT_DB)
+ message(STATUS "Building with BugSplat; database '${BUGSPLAT_DB}'")
+ else (BUGSPLAT_DB)
+ message(WARNING "Building with BugSplat, but no database name set (BUGSPLAT_DB)")
+ endif (BUGSPLAT_DB)
+else (USE_BUGSPLAT)
+ message(STATUS "Not building with BugSplat")
+ if (LINUX)
+ add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
+ add_dependencies(viewer linux-crash-logger-strip-target)
+ elseif (DARWIN)
+ add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
+ add_dependencies(viewer mac-crash-logger)
+ elseif (WINDOWS)
+ add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
+ # add_dependencies(viewer windows-setup windows-crash-logger)
+ add_dependencies(viewer windows-crash-logger)
+ endif (LINUX)
+endif (USE_BUGSPLAT)
+
+add_subdirectory(${VIEWER_PREFIX}newview)
+add_dependencies(viewer secondlife-bin)
+
+add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
+
if (LL_TESTS)
# Define after the custom targets are created so
# individual apps can add themselves as dependencies
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index de81512eef..46ddb9d15b 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -66,7 +66,7 @@ if(WINDOWS)
# Filenames are different for 32/64 bit BugSplat file and we don't
# have any control over them so need to branch.
- if (BUGSPLAT_DB)
+ if (USE_BUGSPLAT)
if(ADDRESS_SIZE EQUAL 32)
set(release_files ${release_files} BugSplat.dll)
set(release_files ${release_files} BugSplatRc.dll)
@@ -76,7 +76,7 @@ if(WINDOWS)
set(release_files ${release_files} BugSplatRc64.dll)
set(release_files ${release_files} BsSndRpt64.exe)
endif(ADDRESS_SIZE EQUAL 32)
- endif (BUGSPLAT_DB)
+ endif (USE_BUGSPLAT)
if (FMODSTUDIO)
set(debug_files ${debug_files} fmodL.dll)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 4932e9044f..4937c2a9d7 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -2,6 +2,7 @@
include(00-Common)
include(LLTestCommand)
include(GoogleMock)
+include(bugsplat)
include(Tut)
#*****************************************************************************
@@ -22,7 +23,6 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
# there is another branch that will conflict heavily with any changes here.
INCLUDE(GoogleMock)
-
IF(LL_TEST_VERBOSE)
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
ENDIF(LL_TEST_VERBOSE)
@@ -87,6 +87,12 @@ INCLUDE(GoogleMock)
IF(LL_TEST_VERBOSE)
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
ENDIF(LL_TEST_VERBOSE)
+
+ if (USE_BUGSPLAT)
+ SET_PROPERTY(SOURCE ${${name}_test_SOURCE_FILES}
+ APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
+ endif (USE_BUGSPLAT)
+
# Headers
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
@@ -224,6 +230,11 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
endif(USESYSTEMLIBS)
+ if (USE_BUGSPLAT)
+ SET_PROPERTY(SOURCE ${source_files}
+ APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
+ endif (USE_BUGSPLAT)
+
# The following was copied to llcorehttp/CMakeLists.txt's texture_load target.
# Any changes made here should be replicated there.
if (WINDOWS)
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index a5770c5528..c81b22e572 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -34,7 +34,6 @@ set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable fo
set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files")
-set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired")
if(LIBS_CLOSED_DIR)
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index 59644b73ce..4edc4c59cd 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -1,25 +1,37 @@
-# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database
-# name.
-if (BUGSPLAT_DB)
- if (USESYSTEMLIBS)
- message(STATUS "Looking for system BugSplat")
- set(BUGSPLAT_FIND_QUIETLY ON)
- set(BUGSPLAT_FIND_REQUIRED ON)
- include(FindBUGSPLAT)
- else (USESYSTEMLIBS)
- message(STATUS "Engaging autobuild BugSplat")
- include(Prebuilt)
- use_prebuilt_binary(bugsplat)
- if (WINDOWS)
- set(BUGSPLAT_LIBRARIES
- ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
- )
- elseif (DARWIN)
- find_library(BUGSPLAT_LIBRARIES BugsplatMac
- PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
- else (WINDOWS)
+if (INSTALL_PROPRIETARY)
+ # Note that viewer_manifest.py makes decision based on BUGSPLAT_DB and not USE_BUGSPLAT
+ if (BUGSPLAT_DB)
+ set(USE_BUGSPLAT ON CACHE BOOL "Use the BugSplat crash reporting system")
+ else (BUGSPLAT_DB)
+ set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
+ endif (BUGSPLAT_DB)
+else (INSTALL_PROPRIETARY)
+ set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
+endif (INSTALL_PROPRIETARY)
+
+if (USE_BUGSPLAT)
+ if (NOT USESYSTEMLIBS)
+ include(Prebuilt)
+ use_prebuilt_binary(bugsplat)
+ if (WINDOWS)
+ set(BUGSPLAT_LIBRARIES
+ ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
+ )
+ elseif (DARWIN)
+ find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED
+ NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
+ else (WINDOWS)
+ message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF")
+ endif (WINDOWS)
+ else (NOT USESYSTEMLIBS)
+ set(BUGSPLAT_FIND_QUIETLY ON)
+ set(BUGSPLAT_FIND_REQUIRED ON)
+ include(FindBUGSPLAT)
+ endif (NOT USESYSTEMLIBS)
+
+ set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name")
- endif (WINDOWS)
set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
- endif (USESYSTEMLIBS)
-endif (BUGSPLAT_DB)
+ set(BUGSPLAT_DEFINE "LL_BUGSPLAT")
+endif (USE_BUGSPLAT)
+
diff --git a/indra/linux_crash_logger/README.txt b/indra/linux_crash_logger/README.txt
new file mode 100644
index 0000000000..6932a8d9c3
--- /dev/null
+++ b/indra/linux_crash_logger/README.txt
@@ -0,0 +1,3 @@
+This component is no longer used in Linden Lab builds.
+Change requests to support continued use by open source
+builds are welcome.
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index cecfadcd91..bafa330f86 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -4,6 +4,7 @@ project(llcommon)
include(00-Common)
include(LLCommon)
+include(bugsplat)
include(Linking)
include(Boost)
include(LLSharedLibs)
@@ -209,9 +210,9 @@ set(llcommon_HEADER_FILES
llqueuedthread.h
llrand.h
llrefcount.h
+ llregex.h
llregistry.h
llrun.h
- llrefcount.h
llsafehandle.h
llsd.h
llsdjson.h
@@ -260,10 +261,10 @@ set(llcommon_HEADER_FILES
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
-if (BUGSPLAT_DB)
- set_source_files_properties(llapp.cpp
- PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
-endif (BUGSPLAT_DB)
+if (USE_BUGSPLAT)
+ set_source_files_properties(${llcommon_SOURCE_FILES}
+ PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
+endif (USE_BUGSPLAT)
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index a90b294550..6064a843ae 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -528,7 +528,12 @@ void LLApp::setupErrorHandling(bool second_instance)
#endif // LL_LINUX
#endif // ! LL_WINDOWS
+
+#ifdef LL_BUGSPLAT
+ // do not start our own error thread
+#else // ! LL_BUGSPLAT
startErrorThread();
+#endif
}
void LLApp::startErrorThread()
@@ -808,7 +813,9 @@ void setup_signals()
act.sa_flags = SA_SIGINFO;
// Synchronous signals
+# ifndef LL_BUGSPLAT
sigaction(SIGABRT, &act, NULL);
+# endif
sigaction(SIGALRM, &act, NULL);
sigaction(SIGBUS, &act, NULL);
sigaction(SIGFPE, &act, NULL);
@@ -845,7 +852,9 @@ void clear_signals()
act.sa_flags = SA_SIGINFO;
// Synchronous signals
+# ifndef LL_BUGSPLAT
sigaction(SIGABRT, &act, NULL);
+# endif
sigaction(SIGALRM, &act, NULL);
sigaction(SIGBUS, &act, NULL);
sigaction(SIGFPE, &act, NULL);
@@ -898,6 +907,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
return;
case SIGABRT:
+ // Note that this handler is not set for SIGABRT when using Bugsplat
// Abort just results in termination of the app, no funky error handling.
if (LLApp::sLogInSignal)
{
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index 245c73e3a2..5fa91b8bf5 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -259,6 +259,10 @@ public:
*/
LLRunner& getRunner() { return mRunner; }
+#ifdef LL_WINDOWS
+ virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { }
+#endif
+
public:
typedef std::map<std::string, std::string> string_map;
string_map mOptionMap; // Contains all command-line options and arguments in a map
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 23419a52a7..111c50af93 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -56,6 +56,10 @@
#include "stringize.h"
#include "llexception.h"
+#if LL_WINDOWS
+#include <excpt.h>
+#endif
+
// static
LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)
{
@@ -249,29 +253,58 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
#if LL_WINDOWS
-void LLCoros::winlevel(const callable_t& callable)
+static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
+
+U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name)
+{
+ // C++ exceptions were logged in toplevelTryWrapper, but not SEH
+ // log SEH exceptions here, to make sure it gets into bugsplat's
+ // report and because __try won't allow std::string operations
+ if (code != STATUS_MSC_EXCEPTION)
+ {
+ LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL;
+ }
+ // Handle bugsplat here, since GetExceptionInformation() can only be
+ // called from within filter for __except(filter), not from __except's {}
+ // Bugsplat should get all exceptions, C++ and SEH
+ LLApp::instance()->reportCrashToBugsplat(exception_infop);
+
+ // Only convert non C++ exceptions.
+ if (code == STATUS_MSC_EXCEPTION)
+ {
+ // C++ exception, go on
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+ else
+ {
+ // handle it
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+}
+
+void LLCoros::winlevel(const std::string& name, const callable_t& callable)
{
__try
{
- callable();
+ toplevelTryWrapper(name, callable);
}
- __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
+ __except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))
{
- // convert to C++ styled exception
+ // convert to C++ styled exception for handlers other than bugsplat
// Note: it might be better to use _se_set_translator
// if you want exception to inherit full callstack
- char integer_string[32];
- sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
+ //
+ // in case of bugsplat this will get to exceptionTerminateHandler and
+ // looks like fiber will terminate application after that
+ char integer_string[512];
+ sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode());
throw std::exception(integer_string);
}
}
#endif
-// Top-level wrapper around caller's coroutine callable.
-// Normally we like to pass strings and such by const reference -- but in this
-// case, we WANT to copy both the name and the callable to our local stack!
-void LLCoros::toplevel(std::string name, callable_t callable)
+void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)
{
// keep the CoroData on this top-level function's stack frame
CoroData corodata(name);
@@ -281,16 +314,12 @@ void LLCoros::toplevel(std::string name, callable_t callable)
// run the code the caller actually wants in the coroutine
try
{
-#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD
- winlevel(callable);
-#else
callable();
-#endif
}
catch (const Stop& exc)
{
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
- << exc.what() << LL_ENDL;
+ << exc.what() << LL_ENDL;
}
catch (const LLContinueError&)
{
@@ -303,10 +332,25 @@ void LLCoros::toplevel(std::string name, callable_t callable)
{
// Any OTHER kind of uncaught exception will cause the viewer to
// crash, hopefully informatively.
- CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
+ LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
+ // to not modify callstack
+ throw;
}
}
+// Top-level wrapper around caller's coroutine callable.
+// Normally we like to pass strings and such by const reference -- but in this
+// case, we WANT to copy both the name and the callable to our local stack!
+void LLCoros::toplevel(std::string name, callable_t callable)
+{
+#if LL_WINDOWS
+ // Can not use __try in functions that require unwinding, so use one more wrapper
+ winlevel(name, callable);
+#else
+ toplevelTryWrapper(name, callable);
+#endif
+}
+
//static
void LLCoros::checkStop()
{
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 38c2356c99..6c0bec3ef9 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -290,11 +290,12 @@ public:
private:
std::string generateDistinctName(const std::string& prefix) const;
- void toplevel(std::string name, callable_t callable);
- struct CoroData;
#if LL_WINDOWS
- static void winlevel(const callable_t& callable);
+ void winlevel(const std::string& name, const callable_t& callable);
#endif
+ void toplevelTryWrapper(const std::string& name, const callable_t& callable);
+ void toplevel(std::string name, callable_t callable);
+ struct CoroData;
static CoroData& get_CoroData(const std::string& caller);
S32 mStackSize;
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index f876b8ee4a..8355df9045 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -442,8 +442,6 @@ namespace
protected:
Globals();
public:
- std::ostringstream messageStream;
- bool messageStreamInUse;
std::string mFatalMessage;
void addCallSite(LLError::CallSite&);
@@ -453,12 +451,7 @@ namespace
CallSiteVector callSites;
};
- Globals::Globals()
- : messageStream(),
- messageStreamInUse(false),
- callSites()
- {
- }
+ Globals::Globals() {}
Globals* Globals::getInstance()
{
@@ -549,7 +542,7 @@ namespace LLError
mFileLevelMap(),
mTagLevelMap(),
mUniqueLogMessages(),
- mCrashFunction(NULL),
+ mCrashFunction([](const std::string&){}),
mTimeFunction(NULL),
mRecorders(),
mShouldLogCallCounter(0)
@@ -728,7 +721,6 @@ namespace
LLError::setDefaultLevel(LLError::LEVEL_INFO);
LLError::setAlwaysFlush(true);
LLError::setEnabledLogTypesMask(0xFFFFFFFF);
- LLError::setFatalFunction(LLError::crashAndLoop);
LLError::setTimeFunction(LLError::utcTime);
// log_to_stderr is only false in the unit and integration tests to keep builds quieter
@@ -1360,57 +1352,7 @@ namespace LLError
}
- std::ostringstream* Log::out()
- {
- LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
-
- if (lock.isLocked())
- {
- Globals* g = Globals::getInstance();
-
- if (!g->messageStreamInUse)
- {
- g->messageStreamInUse = true;
- return &g->messageStream;
- }
- }
-
- return new std::ostringstream;
- }
-
- void Log::flush(std::ostringstream* out, char* message)
- {
- LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
- if (!lock.isLocked())
- {
- return;
- }
-
- if(strlen(out->str().c_str()) < 128)
- {
- strcpy(message, out->str().c_str());
- }
- else
- {
- strncpy(message, out->str().c_str(), 127);
- message[127] = '\0' ;
- }
-
- Globals* g = Globals::getInstance();
- if (out == &g->messageStream)
- {
- g->messageStream.clear();
- g->messageStream.str("");
- g->messageStreamInUse = false;
- }
- else
- {
- delete out;
- }
- return ;
- }
-
- void Log::flush(std::ostringstream* out, const CallSite& site)
+ void Log::flush(const std::ostringstream& out, const CallSite& site)
{
LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);
if (!lock.isLocked())
@@ -1421,22 +1363,11 @@ namespace LLError
Globals* g = Globals::getInstance();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
- std::string message = out->str();
- if (out == &g->messageStream)
- {
- g->messageStream.clear();
- g->messageStream.str("");
- g->messageStreamInUse = false;
- }
- else
- {
- delete out;
- }
-
+ std::string message = out.str();
if (site.mPrintOnce)
{
- std::ostringstream message_stream;
+ std::ostringstream message_stream;
std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
if (messageIter != s->mUniqueLogMessages.end())
@@ -1457,8 +1388,8 @@ namespace LLError
message_stream << "ONCE: ";
s->mUniqueLogMessages[message] = 1;
}
- message_stream << message;
- message = message_stream.str();
+ message_stream << message;
+ message = message_stream.str();
}
writeToRecorders(site, message);
@@ -1466,10 +1397,7 @@ namespace LLError
if (site.mLevel == LEVEL_ERROR)
{
g->mFatalMessage = message;
- if (s->mCrashFunction)
- {
- s->mCrashFunction(message);
- }
+ s->mCrashFunction(message);
}
}
}
@@ -1533,29 +1461,6 @@ namespace LLError
return s->mShouldLogCallCounter;
}
-#if LL_WINDOWS
- // VC80 was optimizing the error away.
- #pragma optimize("", off)
-#endif
- void crashAndLoop(const std::string& message)
- {
- // Now, we go kaboom!
- int* make_me_crash = NULL;
-
- *make_me_crash = 0;
-
- while(true)
- {
- // Loop forever, in case the crash didn't work?
- }
-
- // this is an attempt to let Coverity and other semantic scanners know that this function won't be returning ever.
- exit(EXIT_FAILURE);
- }
-#if LL_WINDOWS
- #pragma optimize("", on)
-#endif
-
std::string utcTime()
{
time_t now = time(NULL);
@@ -1572,33 +1477,7 @@ namespace LLError
namespace LLError
{
- char** LLCallStacks::sBuffer = NULL ;
- S32 LLCallStacks::sIndex = 0 ;
-
- //static
- void LLCallStacks::allocateStackBuffer()
- {
- if(sBuffer == NULL)
- {
- sBuffer = new char*[512] ;
- sBuffer[0] = new char[512 * 128] ;
- for(S32 i = 1 ; i < 512 ; i++)
- {
- sBuffer[i] = sBuffer[i-1] + 128 ;
- }
- sIndex = 0 ;
- }
- }
-
- void LLCallStacks::freeStackBuffer()
- {
- if(sBuffer != NULL)
- {
- delete [] sBuffer[0] ;
- delete [] sBuffer ;
- sBuffer = NULL ;
- }
- }
+ LLCallStacks::StringVector LLCallStacks::sBuffer ;
//static
void LLCallStacks::push(const char* function, const int line)
@@ -1609,33 +1488,24 @@ namespace LLError
return;
}
- if(sBuffer == NULL)
- {
- allocateStackBuffer();
- }
-
- if(sIndex > 511)
+ if(sBuffer.size() > 511)
{
clear() ;
}
- strcpy(sBuffer[sIndex], function) ;
- sprintf(sBuffer[sIndex] + strlen(function), " line: %d ", line) ;
- sIndex++ ;
-
- return ;
+ std::ostringstream out;
+ insert(out, function, line);
+ sBuffer.push_back(out.str());
}
//static
- std::ostringstream* LLCallStacks::insert(const char* function, const int line)
+ void LLCallStacks::insert(std::ostream& out, const char* function, const int line)
{
- std::ostringstream* _out = LLError::Log::out();
- *_out << function << " line " << line << " " ;
- return _out ;
+ out << function << " line " << line << " " ;
}
//static
- void LLCallStacks::end(std::ostringstream* _out)
+ void LLCallStacks::end(const std::ostringstream& out)
{
LLMutexTrylock lock(getMutex<STACKS_MUTEX>(), 5);
if (!lock.isLocked())
@@ -1643,17 +1513,12 @@ namespace LLError
return;
}
- if(sBuffer == NULL)
- {
- allocateStackBuffer();
- }
-
- if(sIndex > 511)
+ if(sBuffer.size() > 511)
{
clear() ;
}
- LLError::Log::flush(_out, sBuffer[sIndex++]) ;
+ sBuffer.push_back(out.str());
}
//static
@@ -1665,33 +1530,30 @@ namespace LLError
return;
}
- if(sIndex > 0)
+ if(! sBuffer.empty())
{
LL_INFOS() << " ************* PRINT OUT LL CALL STACKS ************* " << LL_ENDL;
- while(sIndex > 0)
+ for (StringVector::const_reverse_iterator ri(sBuffer.rbegin()), re(sBuffer.rend());
+ ri != re; ++ri)
{
- sIndex-- ;
- LL_INFOS() << sBuffer[sIndex] << LL_ENDL;
+ LL_INFOS() << (*ri) << LL_ENDL;
}
LL_INFOS() << " *************** END OF LL CALL STACKS *************** " << LL_ENDL;
}
- if(sBuffer != NULL)
- {
- freeStackBuffer();
- }
+ cleanup();
}
//static
void LLCallStacks::clear()
{
- sIndex = 0 ;
+ sBuffer.clear();
}
//static
void LLCallStacks::cleanup()
{
- freeStackBuffer();
+ clear();
}
std::ostream& operator<<(std::ostream& out, const LLStacktrace&)
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index ffaa464d77..d439136ca8 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -29,7 +29,9 @@
#define LL_LLERROR_H
#include <sstream>
+#include <string>
#include <typeinfo>
+#include <vector>
#include "stdtypes.h"
@@ -198,9 +200,7 @@ namespace LLError
{
public:
static bool shouldLog(CallSite&);
- static std::ostringstream* out();
- static void flush(std::ostringstream* out, char* message);
- static void flush(std::ostringstream*, const CallSite&);
+ static void flush(const std::ostringstream&, const CallSite&);
static std::string demangle(const char* mangled);
/// classname<TYPE>()
template <typename T>
@@ -281,18 +281,15 @@ namespace LLError
class LL_COMMON_API LLCallStacks
{
private:
- static char** sBuffer ;
- static S32 sIndex ;
-
- static void allocateStackBuffer();
- static void freeStackBuffer();
+ typedef std::vector<std::string> StringVector;
+ static StringVector sBuffer ;
public:
static void push(const char* function, const int line) ;
- static std::ostringstream* insert(const char* function, const int line) ;
+ static void insert(std::ostream& out, const char* function, const int line) ;
static void print() ;
static void clear() ;
- static void end(std::ostringstream* _out) ;
+ static void end(const std::ostringstream& out) ;
static void cleanup();
};
@@ -306,10 +303,11 @@ namespace LLError
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
#define LL_PUSH_CALLSTACKS() LLError::LLCallStacks::push(__FUNCTION__, __LINE__)
-#define llcallstacks \
- { \
- std::ostringstream* _out = LLError::LLCallStacks::insert(__FUNCTION__, __LINE__) ; \
- (*_out)
+#define llcallstacks \
+ { \
+ std::ostringstream _out; \
+ LLError::LLCallStacks::insert(_out, __FUNCTION__, __LINE__) ; \
+ _out
#define llcallstacksendl \
LLError::End(); \
@@ -355,11 +353,11 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \
lllog_test_()
-#define lllog_test_() \
- if (LL_UNLIKELY(_site.shouldLog())) \
- { \
- std::ostringstream* _out = LLError::Log::out(); \
- (*_out)
+#define lllog_test_() \
+ if (LL_UNLIKELY(_site.shouldLog())) \
+ { \
+ std::ostringstream _out; \
+ _out
#define lllog_site_args_(level, once, tags) \
level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), \
@@ -378,15 +376,27 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// LL_CONT << " for " << t << " seconds" << LL_ENDL;
//
//Such computation is done iff the message will be logged.
-#define LL_CONT (*_out)
+#define LL_CONT _out
#define LL_NEWLINE '\n'
-#define LL_ENDL \
- LLError::End(); \
- LLError::Log::flush(_out, _site); \
- } \
- } while(0)
+// Use this only in LL_ERRS or in a place that LL_ERRS may not be used
+#define LLERROR_CRASH \
+{ \
+ int* make_me_crash = NULL;\
+ *make_me_crash = 0; \
+ exit(*make_me_crash); \
+}
+
+#define LL_ENDL \
+ LLError::End(); \
+ LLError::Log::flush(_out, _site); \
+ if (_site.mLevel == LLError::LEVEL_ERROR) \
+ { \
+ LLERROR_CRASH \
+ } \
+ } \
+ } while(0)
// NEW Macros for debugging, allow the passing of a string tag
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index 25786d5457..e87bb7bf35 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -94,14 +94,16 @@ namespace LLError
*/
typedef boost::function<void(const std::string&)> FatalFunction;
- LL_COMMON_API void crashAndLoop(const std::string& message);
- // Default fatal function: access null pointer and loops forever
LL_COMMON_API void setFatalFunction(const FatalFunction&);
- // The fatal function will be called when an message of LEVEL_ERROR
+ // The fatal function will be called after an message of LEVEL_ERROR
// is logged. Note: supressing a LEVEL_ERROR message from being logged
// (by, for example, setting a class level to LEVEL_NONE), will keep
- // the that message from causing the fatal funciton to be invoked.
+ // that message from causing the fatal function to be invoked.
+ // The passed FatalFunction will be the LAST log function called
+ // before LL_ERRS crashes its caller. A FatalFunction can throw an
+ // exception, or call exit(), to bypass the crash. It MUST disrupt the
+ // flow of control because no caller expects LL_ERRS to return.
LL_COMMON_API FatalFunction getFatalFunction();
// Retrieve the previously-set FatalFunction
@@ -147,14 +149,14 @@ namespace LLError
virtual void recordMessage(LLError::ELevel, const std::string& message) = 0;
// use the level for better display, not for filtering
- virtual bool enabled() { return true; }
+ virtual bool enabled() { return true; }
bool wantsTime();
bool wantsTags();
bool wantsLevel();
bool wantsLocation();
bool wantsFunctionName();
- bool wantsMultiline();
+ bool wantsMultiline();
void showTime(bool show);
void showTags(bool show);
@@ -165,15 +167,35 @@ namespace LLError
protected:
bool mWantsTime;
- bool mWantsTags;
- bool mWantsLevel;
- bool mWantsLocation;
- bool mWantsFunctionName;
- bool mWantsMultiline;
+ bool mWantsTags;
+ bool mWantsLevel;
+ bool mWantsLocation;
+ bool mWantsFunctionName;
+ bool mWantsMultiline;
};
typedef boost::shared_ptr<Recorder> RecorderPtr;
+ /**
+ * Instantiate GenericRecorder with a callable(level, message) to get
+ * control on every log message without having to code an explicit
+ * Recorder subclass.
+ */
+ template <typename CALLABLE>
+ class GenericRecorder: public Recorder
+ {
+ public:
+ GenericRecorder(const CALLABLE& callable):
+ mCallable(callable)
+ {}
+ void recordMessage(LLError::ELevel level, const std::string& message) override
+ {
+ mCallable(level, message);
+ }
+ private:
+ CALLABLE mCallable;
+ };
+
/**
* @NOTE: addRecorder() and removeRecorder() uses the boost::shared_ptr to allow for shared ownership
* while still ensuring that the allocated memory is eventually freed
@@ -181,6 +203,19 @@ namespace LLError
LL_COMMON_API void addRecorder(RecorderPtr);
LL_COMMON_API void removeRecorder(RecorderPtr);
// each error message is passed to each recorder via recordMessage()
+ /**
+ * Call addGenericRecorder() with a callable(level, message) to get
+ * control on every log message without having to code an explicit
+ * Recorder subclass. Save the returned RecorderPtr if you later want to
+ * call removeRecorder().
+ */
+ template <typename CALLABLE>
+ RecorderPtr addGenericRecorder(const CALLABLE& callable)
+ {
+ RecorderPtr ptr{ new GenericRecorder<CALLABLE>(callable) };
+ addRecorder(ptr);
+ return ptr;
+ }
LL_COMMON_API void logToFile(const std::string& filename);
LL_COMMON_API void logToStderr();
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index cf8f8cc6a5..e8ea0ab398 100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -59,7 +59,6 @@ public:
// pump name -- so it should NOT need tweaking for uniqueness.
mReplyPump(LLUUID::generateNewID().asString()),
mExpect(0),
- mPrevFatalFunction(LLError::getFatalFunction()),
// Instantiate a distinct LLLeapListener for this plugin. (Every
// plugin will want its own collection of managed listeners, etc.)
// Pass it a callback to our connect() method, so it can send events
@@ -146,7 +145,9 @@ public:
.listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1));
// For our lifespan, intercept any LL_ERRS so we can notify plugin
- LLError::setFatalFunction(boost::bind(&LLLeapImpl::fatalFunction, this, _1));
+ mRecorder = LLError::addGenericRecorder(
+ [this](LLError::ELevel level, const std::string& message)
+ { onError(level, message); });
// Send child a preliminary event reporting our own reply-pump name --
// which would otherwise be pretty tricky to guess!
@@ -162,8 +163,7 @@ public:
virtual ~LLLeapImpl()
{
LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL;
- // Restore original FatalFunction
- LLError::setFatalFunction(mPrevFatalFunction);
+ LLError::removeRecorder(mRecorder);
}
// Listener for failed launch attempt
@@ -377,28 +377,28 @@ public:
return false;
}
- void fatalFunction(const std::string& error)
+ void onError(LLError::ELevel level, const std::string& error)
{
- // Notify plugin
- LLSD event;
- event["type"] = "error";
- event["error"] = error;
- mReplyPump.post(event);
-
- // All the above really accomplished was to buffer the serialized
- // event in our WritePipe. Have to pump mainloop a couple times to
- // really write it out there... but time out in case we can't write.
- LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
- LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
- LLSD nop;
- F64 until = (LLTimer::getElapsedSeconds() + 2).value();
- while (childin.size() && LLTimer::getElapsedSeconds() < until)
+ if (level == LLError::LEVEL_ERROR)
{
- mainloop.post(nop);
+ // Notify plugin
+ LLSD event;
+ event["type"] = "error";
+ event["error"] = error;
+ mReplyPump.post(event);
+
+ // All the above really accomplished was to buffer the serialized
+ // event in our WritePipe. Have to pump mainloop a couple times to
+ // really write it out there... but time out in case we can't write.
+ LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));
+ LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
+ LLSD nop;
+ F64 until = (LLTimer::getElapsedSeconds() + 2).value();
+ while (childin.size() && LLTimer::getElapsedSeconds() < until)
+ {
+ mainloop.post(nop);
+ }
}
-
- // forward the call to the previous FatalFunction
- mPrevFatalFunction(error);
}
private:
@@ -421,7 +421,7 @@ private:
mStdinConnection, mStdoutConnection, mStdoutDataConnection, mStderrConnection;
boost::scoped_ptr<LLEventPump::Blocker> mBlocker;
LLProcess::ReadPipe::size_type mExpect;
- LLError::FatalFunction mPrevFatalFunction;
+ LLError::RecorderPtr mRecorder;
boost::scoped_ptr<LLLeapListener> mListener;
};
diff --git a/indra/llcommon/llregex.h b/indra/llcommon/llregex.h
new file mode 100644
index 0000000000..2b7f5e47c2
--- /dev/null
+++ b/indra/llcommon/llregex.h
@@ -0,0 +1,89 @@
+/**
+ * @file llregex.h
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLREGEX_H
+#define LLREGEX_H
+#include <boost/regex.hpp>
+
+template <typename S, typename M, typename R>
+LL_COMMON_API bool ll_regex_match(const S& string, M& match, const R& regex)
+{
+ try
+ {
+ return boost::regex_match(string, match, regex);
+ }
+ catch (const std::runtime_error& e)
+ {
+ LL_WARNS() << "error matching with '" << regex.str() << "': "
+ << e.what() << ":\n'" << string << "'" << LL_ENDL;
+ return false;
+ }
+}
+
+template <typename S, typename R>
+LL_COMMON_API bool ll_regex_match(const S& string, const R& regex)
+{
+ try
+ {
+ return boost::regex_match(string, regex);
+ }
+ catch (const std::runtime_error& e)
+ {
+ LL_WARNS() << "error matching with '" << regex.str() << "': "
+ << e.what() << ":\n'" << string << "'" << LL_ENDL;
+ return false;
+ }
+}
+
+template <typename S, typename M, typename R>
+bool ll_regex_search(const S& string, M& match, const R& regex)
+{
+ try
+ {
+ return boost::regex_search(string, match, regex);
+ }
+ catch (const std::runtime_error& e)
+ {
+ LL_WARNS() << "error searching with '" << regex.str() << "': "
+ << e.what() << ":\n'" << string << "'" << LL_ENDL;
+ return false;
+ }
+}
+
+template <typename S, typename R>
+bool ll_regex_search(const S& string, const R& regex)
+{
+ try
+ {
+ return boost::regex_search(string, regex);
+ }
+ catch (const std::runtime_error& e)
+ {
+ LL_WARNS() << "error searching with '" << regex.str() << "': "
+ << e.what() << ":\n'" << string << "'" << LL_ENDL;
+ return false;
+ }
+}
+#endif // LLREGEX_H
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index ad933154c2..6b1986d0e9 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -38,11 +38,6 @@
#include <sstream>
#include <stdexcept>
-namespace {
-void log(LLError::ELevel level,
- const char* p1, const char* p2, const char* p3, const char* p4);
-} // anonymous namespace
-
// Our master list of all LLSingletons is itself an LLSingleton. We used to
// store it in a function-local static, but that could get destroyed before
// the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to
@@ -218,8 +213,8 @@ void LLSingletonBase::pop_initializing()
if (list.empty())
{
- logerrs("Underflow in stack of currently-initializing LLSingletons at ",
- classname(this).c_str(), "::getInstance()");
+ logerrs({"Underflow in stack of currently-initializing LLSingletons at ",
+ classname(this), "::getInstance()"});
}
// Now we know list.back() exists: capture it
@@ -240,9 +235,9 @@ void LLSingletonBase::pop_initializing()
// Now validate the newly-popped LLSingleton.
if (back != this)
{
- logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ",
- classname(this).c_str(), "::getInstance() trying to pop ",
- classname(back).c_str());
+ logerrs({"Push/pop mismatch in stack of currently-initializing LLSingletons: ",
+ classname(this), "::getInstance() trying to pop ",
+ classname(back)});
}
// log AFTER popping so logging singletons don't cry circularity
@@ -331,15 +326,15 @@ void LLSingletonBase::capture_dependency()
//
// Example: LLNotifications singleton initializes default channels.
// Channels register themselves with singleton once done.
- logdebugs("LLSingleton circularity: ", out.str().c_str(),
- classname(this).c_str(), "");
+ logdebugs({"LLSingleton circularity: ", out.str(),
+ classname(this)});
}
else
{
// Actual circularity with other singleton (or single singleton is used extensively).
// Dependency can be unclear.
- logwarns("LLSingleton circularity: ", out.str().c_str(),
- classname(this).c_str(), "");
+ logwarns({"LLSingleton circularity: ", out.str(),
+ classname(this)});
}
}
else
@@ -352,8 +347,8 @@ void LLSingletonBase::capture_dependency()
if (current->mDepends.insert(this).second)
{
// only log the FIRST time we hit this dependency!
- logdebugs(classname(current).c_str(),
- " depends on ", classname(this).c_str());
+ logdebugs({classname(current),
+ " depends on ", classname(this)});
}
}
}
@@ -401,7 +396,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort()
void LLSingletonBase::cleanup_()
{
- logdebugs("calling ", classname(this).c_str(), "::cleanupSingleton()");
+ logdebugs({"calling ", classname(this), "::cleanupSingleton()"});
try
{
cleanupSingleton();
@@ -427,23 +422,23 @@ void LLSingletonBase::deleteAll()
if (! sp->mDeleteSingleton)
{
// This Should Not Happen... but carry on.
- logwarns(name.c_str(), "::mDeleteSingleton not initialized!");
+ logwarns({name, "::mDeleteSingleton not initialized!"});
}
else
{
// properly initialized: call it.
- logdebugs("calling ", name.c_str(), "::deleteSingleton()");
+ logdebugs({"calling ", name, "::deleteSingleton()"});
// From this point on, DO NOT DEREFERENCE sp!
sp->mDeleteSingleton();
}
}
catch (const std::exception& e)
{
- logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what());
+ logwarns({"Exception in ", name, "::deleteSingleton(): ", e.what()});
}
catch (...)
{
- logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()");
+ logwarns({"Unknown exception in ", name, "::deleteSingleton()"});
}
}
}
@@ -451,49 +446,40 @@ void LLSingletonBase::deleteAll()
/*---------------------------- Logging helpers -----------------------------*/
namespace {
-void log(LLError::ELevel level,
- const char* p1, const char* p2, const char* p3, const char* p4)
+std::ostream& operator<<(std::ostream& out, const LLSingletonBase::string_params& args)
{
- LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
+ // However many args there are in args, stream each of them to 'out'.
+ for (auto arg : args)
+ {
+ out << arg;
+ }
+ return out;
}
} // anonymous namespace
//static
-void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4)
+void LLSingletonBase::logwarns(const string_params& args)
{
- log(LLError::LEVEL_WARN, p1, p2, p3, p4);
+ LL_WARNS("LLSingleton") << args << LL_ENDL;
}
//static
-void LLSingletonBase::loginfos(const char* p1, const char* p2, const char* p3, const char* p4)
+void LLSingletonBase::loginfos(const string_params& args)
{
- log(LLError::LEVEL_INFO, p1, p2, p3, p4);
+ LL_INFOS("LLSingleton") << args << LL_ENDL;
}
//static
-void LLSingletonBase::logdebugs(const char* p1, const char* p2, const char* p3, const char* p4)
+void LLSingletonBase::logdebugs(const string_params& args)
{
- log(LLError::LEVEL_DEBUG, p1, p2, p3, p4);
+ LL_DEBUGS("LLSingleton") << args << LL_ENDL;
}
//static
-void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4)
+void LLSingletonBase::logerrs(const string_params& args)
{
- log(LLError::LEVEL_ERROR, p1, p2, p3, p4);
- // The other important side effect of LL_ERRS() is
- // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG)
- std::ostringstream out;
- out << p1 << p2 << p3 << p4;
- auto crash = LLError::getFatalFunction();
- if (crash)
- {
- crash(out.str());
- }
- else
- {
- LLError::crashAndLoop(out.str());
- }
+ LL_ERRS("LLSingleton") << args << LL_ENDL;
}
std::string LLSingletonBase::demangle(const char* mangled)
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 30a5b21cf8..7c81d65a8b 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -27,9 +27,10 @@
#include <boost/noncopyable.hpp>
#include <boost/unordered_set.hpp>
+#include <initializer_list>
#include <list>
-#include <vector>
#include <typeinfo>
+#include <vector>
#include "mutex.h"
#include "lockstatic.h"
#include "llthread.h" // on_main_thread()
@@ -111,14 +112,13 @@ protected:
void capture_dependency();
// delegate logging calls to llsingleton.cpp
- static void logerrs(const char* p1, const char* p2="",
- const char* p3="", const char* p4="");
- static void logwarns(const char* p1, const char* p2="",
- const char* p3="", const char* p4="");
- static void loginfos(const char* p1, const char* p2="",
- const char* p3="", const char* p4="");
- static void logdebugs(const char* p1, const char* p2="",
- const char* p3="", const char* p4="");
+public:
+ typedef std::initializer_list<const std::string> string_params;
+protected:
+ static void logerrs (const string_params&);
+ static void logwarns (const string_params&);
+ static void loginfos (const string_params&);
+ static void logdebugs(const string_params&);
static std::string demangle(const char* mangled);
// these classname() declarations restate template functions declared in
// llerror.h because we avoid #including that here
@@ -327,8 +327,8 @@ private:
// init stack to its previous size BEFORE logging so log-machinery
// LLSingletons don't record a dependency on DERIVED_TYPE!
LLSingleton_manage_master<DERIVED_TYPE>().reset_initializing(prev_size);
- logwarns("Error constructing ", classname<DERIVED_TYPE>().c_str(),
- ": ", err.what());
+ logwarns({"Error constructing ", classname<DERIVED_TYPE>(),
+ ": ", err.what()});
// There isn't a separate EInitState value meaning "we attempted
// to construct this LLSingleton subclass but could not," so use
// DELETED. That seems slightly more appropriate than UNINITIALIZED.
@@ -356,8 +356,8 @@ private:
// BEFORE logging, so log-machinery LLSingletons don't record a
// dependency on DERIVED_TYPE!
pop_initializing(lk->mInstance);
- logwarns("Error in ", classname<DERIVED_TYPE>().c_str(),
- "::initSingleton(): ", err.what());
+ logwarns({"Error in ", classname<DERIVED_TYPE>(),
+ "::initSingleton(): ", err.what()});
// Get rid of the instance entirely. This call depends on our
// recursive_mutex. We could have a deleteSingleton(LockStatic&)
// overload and pass lk, but we don't strictly need it.
@@ -506,9 +506,9 @@ public:
case CONSTRUCTING:
// here if DERIVED_TYPE's constructor (directly or indirectly)
// calls DERIVED_TYPE::getInstance()
- logerrs("Tried to access singleton ",
- classname<DERIVED_TYPE>().c_str(),
- " from singleton constructor!");
+ logerrs({"Tried to access singleton ",
+ classname<DERIVED_TYPE>(),
+ " from singleton constructor!"});
return nullptr;
case INITIALIZING:
@@ -523,9 +523,9 @@ public:
case DELETED:
// called after deleteSingleton()
- logwarns("Trying to access deleted singleton ",
- classname<DERIVED_TYPE>().c_str(),
- " -- creating new instance");
+ logwarns({"Trying to access deleted singleton ",
+ classname<DERIVED_TYPE>(),
+ " -- creating new instance"});
// fall through
case UNINITIALIZED:
case QUEUED:
@@ -552,8 +552,8 @@ public:
} // unlock 'lk'
// Per the comment block above, dispatch to the main thread.
- loginfos(classname<DERIVED_TYPE>().c_str(),
- "::getInstance() dispatching to main thread");
+ loginfos({classname<DERIVED_TYPE>(),
+ "::getInstance() dispatching to main thread"});
auto instance = LLMainThreadTask::dispatch(
[](){
// VERY IMPORTANT to call getInstance() on the main thread,
@@ -563,16 +563,16 @@ public:
// the main thread processes them, only the FIRST such request
// actually constructs the instance -- every subsequent one
// simply returns the existing instance.
- loginfos(classname<DERIVED_TYPE>().c_str(),
- "::getInstance() on main thread");
+ loginfos({classname<DERIVED_TYPE>(),
+ "::getInstance() on main thread"});
return getInstance();
});
// record the dependency chain tracked on THIS thread, not the main
// thread (consider a getInstance() overload with a tag param that
// suppresses dep tracking when dispatched to the main thread)
capture_dependency(instance);
- loginfos(classname<DERIVED_TYPE>().c_str(),
- "::getInstance() returning on requesting thread");
+ loginfos({classname<DERIVED_TYPE>(),
+ "::getInstance() returning on requesting thread"});
return instance;
}
@@ -641,16 +641,16 @@ private:
// For organizational purposes this function shouldn't be called twice
if (lk->mInitState != super::UNINITIALIZED)
{
- super::logerrs("Tried to initialize singleton ",
- super::template classname<DERIVED_TYPE>().c_str(),
- " twice!");
+ super::logerrs({"Tried to initialize singleton ",
+ super::template classname<DERIVED_TYPE>(),
+ " twice!"});
return nullptr;
}
else if (on_main_thread())
{
// on the main thread, simply construct instance while holding lock
- super::logdebugs(super::template classname<DERIVED_TYPE>().c_str(),
- "::initParamSingleton()");
+ super::logdebugs({super::template classname<DERIVED_TYPE>(),
+ "::initParamSingleton()"});
super::constructSingleton(lk, std::forward<Args>(args)...);
return lk->mInstance;
}
@@ -662,8 +662,8 @@ private:
lk->mInitState = super::QUEUED;
// very important to unlock here so main thread can actually process
lk.unlock();
- super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
- "::initParamSingleton() dispatching to main thread");
+ super::loginfos({super::template classname<DERIVED_TYPE>(),
+ "::initParamSingleton() dispatching to main thread"});
// Normally it would be the height of folly to reference-bind
// 'args' into a lambda to be executed on some other thread! By
// the time that thread executed the lambda, the references would
@@ -674,12 +674,12 @@ private:
// references.
auto instance = LLMainThreadTask::dispatch(
[&](){
- super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
- "::initParamSingleton() on main thread");
+ super::loginfos({super::template classname<DERIVED_TYPE>(),
+ "::initParamSingleton() on main thread"});
return initParamSingleton_(std::forward<Args>(args)...);
});
- super::loginfos(super::template classname<DERIVED_TYPE>().c_str(),
- "::initParamSingleton() returning on requesting thread");
+ super::loginfos({super::template classname<DERIVED_TYPE>(),
+ "::initParamSingleton() returning on requesting thread"});
return instance;
}
}
@@ -707,14 +707,14 @@ public:
{
case super::UNINITIALIZED:
case super::QUEUED:
- super::logerrs("Uninitialized param singleton ",
- super::template classname<DERIVED_TYPE>().c_str());
+ super::logerrs({"Uninitialized param singleton ",
+ super::template classname<DERIVED_TYPE>()});
break;
case super::CONSTRUCTING:
- super::logerrs("Tried to access param singleton ",
- super::template classname<DERIVED_TYPE>().c_str(),
- " from singleton constructor!");
+ super::logerrs({"Tried to access param singleton ",
+ super::template classname<DERIVED_TYPE>(),
+ " from singleton constructor!"});
break;
case super::INITIALIZING:
@@ -726,8 +726,8 @@ public:
return lk->mInstance;
case super::DELETED:
- super::logerrs("Trying to access deleted param singleton ",
- super::template classname<DERIVED_TYPE>().c_str());
+ super::logerrs({"Trying to access deleted param singleton ",
+ super::template classname<DERIVED_TYPE>()});
break;
}
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 4e61fb8a58..2ca15a31c6 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -43,12 +43,12 @@
#include "llerrorcontrol.h"
#include "llevents.h"
#include "llformat.h"
+#include "llregex.h"
#include "lltimer.h"
#include "llsdserialize.h"
#include "llsdutil.h"
#include <boost/bind.hpp>
#include <boost/circular_buffer.hpp>
-#include <boost/regex.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/range.hpp>
@@ -101,39 +101,6 @@ static const F32 MEM_INFO_THROTTLE = 20;
// dropped below the login framerate, we'd have very little additional data.
static const F32 MEM_INFO_WINDOW = 10*60;
-// Wrap boost::regex_match() with a function that doesn't throw.
-template <typename S, typename M, typename R>
-static bool regex_match_no_exc(const S& string, M& match, const R& regex)
-{
- try
- {
- return boost::regex_match(string, match, regex);
- }
- catch (const std::runtime_error& e)
- {
- LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': "
- << e.what() << ":\n'" << string << "'" << LL_ENDL;
- return false;
- }
-}
-
-// Wrap boost::regex_search() with a function that doesn't throw.
-template <typename S, typename M, typename R>
-static bool regex_search_no_exc(const S& string, M& match, const R& regex)
-{
- try
- {
- return boost::regex_search(string, match, regex);
- }
- catch (const std::runtime_error& e)
- {
- LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': "
- << e.what() << ":\n'" << string << "'" << LL_ENDL;
- return false;
- }
-}
-
-
LLOSInfo::LLOSInfo() :
mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("")
{
@@ -377,7 +344,7 @@ LLOSInfo::LLOSInfo() :
boost::smatch matched;
std::string glibc_version(gnu_get_libc_version());
- if ( regex_match_no_exc(glibc_version, matched, os_version_parse) )
+ if ( ll_regex_match(glibc_version, matched, os_version_parse) )
{
LL_INFOS("AppInit") << "Using glibc version '" << glibc_version << "' as OS version" << LL_ENDL;
@@ -1045,7 +1012,7 @@ LLSD LLMemoryInfo::loadStatsMap()
while (std::getline(meminfo, line))
{
LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL;
- if (regex_match_no_exc(line, matched, stat_rx))
+ if (ll_regex_match(line, matched, stat_rx))
{
// e.g. "MemTotal: 4108424 kB"
LLSD::String key(matched[1].first, matched[1].second);
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 98905f3b71..6d531d842d 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -354,8 +354,9 @@ void LLThread::setQuitting()
{
mStatus = QUITTING;
}
+ // It's only safe to remove mRunCondition if all locked threads were notified
+ mRunCondition->broadcast();
mDataLock->unlock();
- wake();
}
// static
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 9942bc0cf8..22711a83d2 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -276,7 +276,7 @@ std::string LLURI::escapePathAndData(const std::string &str)
std::string fragment;
size_t fragment_pos = str.find('#');
- if (fragment_pos != std::string::npos)
+ if ((fragment_pos != std::string::npos) && (fragment_pos > delim_pos))
{
query = str.substr(path_size, fragment_pos - path_size);
fragment = str.substr(fragment_pos);
diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index 8e1f4c14ac..148c18aabe 100644
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
@@ -26,6 +26,7 @@
*/
#include <vector>
+#include <stdexcept>
#include "linden_common.h"
@@ -69,21 +70,41 @@ namespace
namespace
{
- static bool fatalWasCalled;
- void fatalCall(const std::string&) { fatalWasCalled = true; }
+ static bool fatalWasCalled = false;
+ struct FatalWasCalled: public std::runtime_error
+ {
+ FatalWasCalled(const std::string& what): std::runtime_error(what) {}
+ };
+ void fatalCall(const std::string& msg) { throw FatalWasCalled(msg); }
}
+// Because we use LLError::setFatalFunction(fatalCall), any LL_ERRS call we
+// issue will throw FatalWasCalled. But we want the test program to continue.
+// So instead of writing:
+// LL_ERRS("tag") << "some message" << LL_ENDL;
+// write:
+// CATCH(LL_ERRS("tag"), "some message");
+#define CATCH(logcall, expr) \
+ try \
+ { \
+ logcall << expr << LL_ENDL; \
+ } \
+ catch (const FatalWasCalled&) \
+ { \
+ fatalWasCalled = true; \
+ }
+
namespace tut
{
class TestRecorder : public LLError::Recorder
{
public:
TestRecorder()
- {
- showTime(false);
- }
+ {
+ showTime(false);
+ }
virtual ~TestRecorder()
- {}
+ {}
virtual void recordMessage(LLError::ELevel level,
const std::string& message)
@@ -252,7 +273,7 @@ namespace
LL_DEBUGS("WriteTag","AnotherTag") << "one" << LL_ENDL;
LL_INFOS("WriteTag") << "two" << LL_ENDL;
LL_WARNS("WriteTag") << "three" << LL_ENDL;
- LL_ERRS("WriteTag") << "four" << LL_ENDL;
+ CATCH(LL_ERRS("WriteTag"), "four");
}
};
@@ -380,7 +401,7 @@ namespace
std::string errorReturningLocation()
{
- LL_ERRS() << "die" << LL_ENDL; int this_line = __LINE__;
+ int this_line = __LINE__; CATCH(LL_ERRS(), "die");
return locationString(this_line);
}
}
@@ -701,7 +722,7 @@ public:
static void doDebug() { LL_DEBUGS() << "add dice" << LL_ENDL; }
static void doInfo() { LL_INFOS() << "any idea" << LL_ENDL; }
static void doWarn() { LL_WARNS() << "aim west" << LL_ENDL; }
- static void doError() { LL_ERRS() << "ate eels" << LL_ENDL; }
+ static void doError() { CATCH(LL_ERRS(), "ate eels"); }
static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }
};
@@ -712,7 +733,7 @@ public:
static void doDebug() { LL_DEBUGS() << "bed down" << LL_ENDL; }
static void doInfo() { LL_INFOS() << "buy iron" << LL_ENDL; }
static void doWarn() { LL_WARNS() << "bad word" << LL_ENDL; }
- static void doError() { LL_ERRS() << "big easy" << LL_ENDL; }
+ static void doError() { CATCH(LL_ERRS(), "big easy"); }
static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }
};
@@ -874,13 +895,10 @@ namespace tut
namespace
{
std::string writeTagWithSpaceReturningLocation()
- {
- LL_DEBUGS("Write Tag") << "not allowed" << LL_ENDL; int this_line = __LINE__;
-
- std::ostringstream location;
- location << LLError::abbreviateFile(__FILE__).c_str() << "(" << this_line << ")";
- return location.str();
- }
+ {
+ int this_line = __LINE__; CATCH(LL_DEBUGS("Write Tag"), "not allowed");
+ return locationString(this_line);
+ }
};
namespace tut
@@ -894,9 +912,9 @@ namespace tut
std::string location = writeTagWithSpaceReturningLocation();
std::string expected = "Space is not allowed in a log tag at " + location;
- ensure_message_field_equals(0, LEVEL_FIELD, "ERROR");
- ensure_message_field_equals(0, MSG_FIELD, expected);
- ensure("fatal callback called", fatalWasCalled);
+ ensure_message_field_equals(0, LEVEL_FIELD, "ERROR");
+ ensure_message_field_equals(0, MSG_FIELD, expected);
+ ensure("fatal callback called", fatalWasCalled);
}
}
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index b07d5afbd8..3779fb41bc 100644
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
@@ -44,10 +44,6 @@
#include <list>
#include <string>
-// statically reference the function in test.cpp... it's short, we could
-// replicate, but better to reuse
-extern void wouldHaveCrashed(const std::string& message);
-
struct WrapLLErrs
{
WrapLLErrs():
@@ -59,7 +55,8 @@ struct WrapLLErrs
mPriorFatal(LLError::getFatalFunction())
{
// Make LL_ERRS call our own operator() method
- LLError::setFatalFunction(boost::bind(&WrapLLErrs::operator(), this, _1));
+ LLError::setFatalFunction(
+ [this](const std::string& message){ (*this)(message); });
}
~WrapLLErrs()
@@ -199,11 +196,13 @@ public:
// with that output. If it turns out that saveAndResetSettings() has
// some bad effect, give up and just let the DEBUG level log messages
// display.
- : boost::noncopyable(),
+ : boost::noncopyable(),
+ mFatalFunction(LLError::getFatalFunction()),
mOldSettings(LLError::saveAndResetSettings()),
- mRecorder(new CaptureLogRecorder())
+ mRecorder(new CaptureLogRecorder())
{
- LLError::setFatalFunction(wouldHaveCrashed);
+ // reinstate the FatalFunction we just reset
+ LLError::setFatalFunction(mFatalFunction);
LLError::setDefaultLevel(level);
LLError::addRecorder(mRecorder);
}
@@ -219,17 +218,18 @@ public:
/// for the sought string.
std::string messageWith(const std::string& search, bool required=true)
{
- return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required);
+ return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required);
}
std::ostream& streamto(std::ostream& out) const
{
- return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out);
+ return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out);
}
private:
+ LLError::FatalFunction mFatalFunction;
LLError::SettingsStoragePtr mOldSettings;
- LLError::RecorderPtr mRecorder;
+ LLError::RecorderPtr mRecorder;
};
#endif /* ! defined(LL_WRAPLLERRS_H) */
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 240ea2da83..8bb6a657b1 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -13,6 +13,7 @@ include(LLAddBuildTest)
include(LLMessage)
include(LLCommon)
include(Tut)
+include(bugsplat)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/indra/llcorehttp/_httpreplyqueue.cpp b/indra/llcorehttp/_httpreplyqueue.cpp
index 2b138f3ad5..229bfdbe07 100644
--- a/indra/llcorehttp/_httpreplyqueue.cpp
+++ b/indra/llcorehttp/_httpreplyqueue.cpp
@@ -56,7 +56,6 @@ void HttpReplyQueue::addOp(const HttpReplyQueue::opPtr_t &op)
mQueue.push_back(op);
}
- mQueueCV.notify_all();
}
diff --git a/indra/llcorehttp/_httpreplyqueue.h b/indra/llcorehttp/_httpreplyqueue.h
index 928ee10a83..33e205c1c9 100644
--- a/indra/llcorehttp/_httpreplyqueue.h
+++ b/indra/llcorehttp/_httpreplyqueue.h
@@ -98,7 +98,6 @@ protected:
OpContainer mQueue;
LLCoreInt::HttpMutex mQueueMutex;
- LLCoreInt::HttpConditionVariable mQueueCV;
}; // end class HttpReplyQueue
diff --git a/indra/llcorehttp/_httprequestqueue.cpp b/indra/llcorehttp/_httprequestqueue.cpp
index c6f4ad789f..ad72bdcce6 100644
--- a/indra/llcorehttp/_httprequestqueue.cpp
+++ b/indra/llcorehttp/_httprequestqueue.cpp
@@ -142,13 +142,19 @@ void HttpRequestQueue::wakeAll()
}
-void HttpRequestQueue::stopQueue()
+bool HttpRequestQueue::stopQueue()
{
{
HttpScopedLock lock(mQueueMutex);
- mQueueStopped = true;
- wakeAll();
+ if (!mQueueStopped)
+ {
+ mQueueStopped = true;
+ wakeAll();
+ return true;
+ }
+ wakeAll();
+ return false;
}
}
diff --git a/indra/llcorehttp/_httprequestqueue.h b/indra/llcorehttp/_httprequestqueue.h
index 3c3d134b07..f0296f30e3 100644
--- a/indra/llcorehttp/_httprequestqueue.h
+++ b/indra/llcorehttp/_httprequestqueue.h
@@ -124,7 +124,7 @@ public:
/// them on their way.
///
/// Threading: callable by any thread.
- void stopQueue();
+ bool stopQueue();
protected:
static HttpRequestQueue * sInstance;
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 34268d94f6..56f52f1b09 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -87,7 +87,11 @@ HttpService::~HttpService()
// is a bit tricky.
if (mRequestQueue)
{
- mRequestQueue->stopQueue();
+ if (mRequestQueue->stopQueue())
+ {
+ // Give mRequestQueue a chance to finish
+ ms_sleep(10);
+ }
}
if (mThread)
diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp
index df5aa52fa9..c6365e5091 100644
--- a/indra/llcorehttp/httpoptions.cpp
+++ b/indra/llcorehttp/httpoptions.cpp
@@ -32,6 +32,7 @@
namespace LLCore
{
+ bool HttpOptions::sDefaultVerifyPeer = false;
HttpOptions::HttpOptions() :
mWantHeaders(false),
@@ -43,7 +44,7 @@ HttpOptions::HttpOptions() :
mMaxRetryBackoff(HTTP_RETRY_BACKOFF_MAX_DEFAULT),
mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),
mFollowRedirects(true),
- mVerifyPeer(false),
+ mVerifyPeer(sDefaultVerifyPeer),
mVerifyHost(false),
mDNSCacheTimeout(-1L),
mNoBody(false)
@@ -122,7 +123,15 @@ void HttpOptions::setHeadersOnly(bool nobody)
{
mNoBody = nobody;
if (mNoBody)
+ {
setWantHeaders(true);
+ setSSLVerifyPeer(false);
+ }
+}
+
+void HttpOptions::setDefaultSSLVerifyPeer(bool verify)
+{
+ sDefaultVerifyPeer = verify;
}
} // end namespace LLCore
diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h
index 8a6de61b04..41f71896b0 100644
--- a/indra/llcorehttp/httpoptions.h
+++ b/indra/llcorehttp/httpoptions.h
@@ -143,7 +143,7 @@ public:
/// Instructs the LLCore::HTTPRequest to verify that the exchanged security
/// certificate is authentic.
- /// Default: false
+ /// Default: sDefaultVerifyPeer
void setSSLVerifyPeer(bool verify);
bool getSSLVerifyPeer() const
{
@@ -177,6 +177,13 @@ public:
{
return mNoBody;
}
+
+ /// Sets default behavior for verifying that the name in the
+ /// security certificate matches the name of the host contacted.
+ /// Defaults false if not set, but should be set according to
+ /// viewer's initialization options and command argunments, see
+ /// NoVerifySSLCert
+ static void setDefaultSSLVerifyPeer(bool verify);
protected:
bool mWantHeaders;
@@ -192,6 +199,8 @@ protected:
bool mVerifyHost;
int mDNSCacheTimeout;
bool mNoBody;
+
+ static bool sDefaultVerifyPeer;
}; // end class HttpOptions
diff --git a/indra/llcrashlogger/README.txt b/indra/llcrashlogger/README.txt
new file mode 100644
index 0000000000..6932a8d9c3
--- /dev/null
+++ b/indra/llcrashlogger/README.txt
@@ -0,0 +1,3 @@
+This component is no longer used in Linden Lab builds.
+Change requests to support continued use by open source
+builds are welcome.
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 62fcdaf545..e02f3a6306 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -411,6 +411,7 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setTimeout(timeout);
+ httpOpts->setSSLVerifyPeer(false);
for(int i = 0; i < retries; ++i)
{
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index 293ada7548..28b8e8c06d 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -11,6 +11,7 @@ include(LLKDU)
include(LLImageJ2COJ)
include(ZLIB)
include(LLAddBuildTest)
+include(bugsplat)
include(Tut)
include_directories(
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index aed8943439..983c7c2406 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1456,7 +1456,7 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
setDataAndSize(new_data, new_width, new_height, components);
}
}
- else
+ else try
{
// copy out existing image data
S32 temp_data_size = old_width * old_height * components;
@@ -1490,6 +1490,11 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
}
}
}
+ catch (std::bad_alloc&) // for temp_buffer
+ {
+ LL_WARNS() << "Failed to allocate temporary image buffer" << LL_ENDL;
+ return false;
+ }
return true ;
}
diff --git a/indra/llinventory/lllandmark.cpp b/indra/llinventory/lllandmark.cpp
index 4c6075d6b5..bd7ab3c2c8 100644
--- a/indra/llinventory/lllandmark.cpp
+++ b/indra/llinventory/lllandmark.cpp
@@ -103,60 +103,104 @@ LLVector3 LLLandmark::getRegionPos() const
// static
-LLLandmark* LLLandmark::constructFromString(const char *buffer)
+LLLandmark* LLLandmark::constructFromString(const char *buffer, const S32 buffer_size)
{
- const char* cur = buffer;
S32 chars_read = 0;
+ S32 chars_read_total = 0;
S32 count = 0;
U32 version = 0;
+ bool bad_block = false;
+ LLLandmark* result = NULL;
+
// read version
- count = sscanf( cur, "Landmark version %u\n%n", &version, &chars_read );
- if(count != 1)
- {
- goto error;
- }
+ count = sscanf( buffer, "Landmark version %u\n%n", &version, &chars_read );
+ chars_read_total += chars_read;
- if(version == 1)
- {
- LLVector3d pos;
- cur += chars_read;
- // read position
- count = sscanf( cur, "position %lf %lf %lf\n%n", pos.mdV+VX, pos.mdV+VY, pos.mdV+VZ, &chars_read );
- if( count != 3 )
- {
- goto error;
- }
- cur += chars_read;
- // LL_INFOS() << "Landmark read: " << pos << LL_ENDL;
-
- return new LLLandmark(pos);
- }
- else if(version == 2)
- {
- // *NOTE: Changing the buffer size will require changing the
- // scanf call below.
- char region_id_str[MAX_STRING]; /* Flawfinder: ignore */
- LLVector3 pos;
- cur += chars_read;
- count = sscanf( /* Flawfinder: ignore */
- cur,
- "region_id %254s\n%n",
- region_id_str, &chars_read);
- if(count != 1) goto error;
- cur += chars_read;
- count = sscanf(cur, "local_pos %f %f %f\n%n", pos.mV+VX, pos.mV+VY, pos.mV+VZ, &chars_read);
- if(count != 3) goto error;
- cur += chars_read;
- LLLandmark* lm = new LLLandmark;
- lm->mRegionID.set(region_id_str);
- lm->mRegionPos = pos;
- return lm;
- }
+ if (count != 1
+ || chars_read_total >= buffer_size)
+ {
+ bad_block = true;
+ }
+
+ if (!bad_block)
+ {
+ switch (version)
+ {
+ case 1:
+ {
+ LLVector3d pos;
+ // read position
+ count = sscanf(buffer + chars_read_total, "position %lf %lf %lf\n%n", pos.mdV + VX, pos.mdV + VY, pos.mdV + VZ, &chars_read);
+ if (count != 3)
+ {
+ bad_block = true;
+ }
+ else
+ {
+ LL_DEBUGS("Landmark") << "Landmark read: " << pos << LL_ENDL;
+ result = new LLLandmark(pos);
+ }
+ break;
+ }
+ case 2:
+ {
+ // *NOTE: Changing the buffer size will require changing the
+ // scanf call below.
+ char region_id_str[MAX_STRING];
+ LLVector3 pos;
+ LLUUID region_id;
+ count = sscanf( buffer + chars_read_total,
+ "region_id %254s\n%n",
+ region_id_str,
+ &chars_read);
+ chars_read_total += chars_read;
+
+ if (count != 1
+ || chars_read_total >= buffer_size
+ || !LLUUID::validate(region_id_str))
+ {
+ bad_block = true;
+ }
+
+ if (!bad_block)
+ {
+ region_id.set(region_id_str);
+ if (region_id.isNull())
+ {
+ bad_block = true;
+ }
+ }
+
+ if (!bad_block)
+ {
+ count = sscanf(buffer + chars_read_total, "local_pos %f %f %f\n%n", pos.mV + VX, pos.mV + VY, pos.mV + VZ, &chars_read);
+ if (count != 3)
+ {
+ bad_block = true;
+ }
+ else
+ {
+ result = new LLLandmark;
+ result->mRegionID = region_id;
+ result->mRegionPos = pos;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ LL_INFOS("Landmark") << "Encountered Unknown landmark version " << version << LL_ENDL;
+ break;
+ }
+ }
+ }
- error:
- LL_INFOS() << "Bad Landmark Asset: bad _DATA_ block." << LL_ENDL;
- return NULL;
+ if (bad_block)
+ {
+ LL_INFOS("Landmark") << "Bad Landmark Asset: bad _DATA_ block." << LL_ENDL;
+ }
+ return result;
}
@@ -176,7 +220,7 @@ void LLLandmark::requestRegionHandle(
if(region_id.isNull())
{
// don't bother with checking - it's 0.
- LL_DEBUGS() << "requestRegionHandle: null" << LL_ENDL;
+ LL_DEBUGS("Landmark") << "requestRegionHandle: null" << LL_ENDL;
if(callback)
{
const U64 U64_ZERO = 0;
@@ -187,7 +231,7 @@ void LLLandmark::requestRegionHandle(
{
if(region_id == mLocalRegion.first)
{
- LL_DEBUGS() << "requestRegionHandle: local" << LL_ENDL;
+ LL_DEBUGS("Landmark") << "requestRegionHandle: local" << LL_ENDL;
if(callback)
{
callback(region_id, mLocalRegion.second);
@@ -198,13 +242,13 @@ void LLLandmark::requestRegionHandle(
region_map_t::iterator it = mRegions.find(region_id);
if(it == mRegions.end())
{
- LL_DEBUGS() << "requestRegionHandle: upstream" << LL_ENDL;
+ LL_DEBUGS("Landmark") << "requestRegionHandle: upstream" << LL_ENDL;
if(callback)
{
region_callback_map_t::value_type vt(region_id, callback);
sRegionCallbackMap.insert(vt);
}
- LL_DEBUGS() << "Landmark requesting information about: "
+ LL_DEBUGS("Landmark") << "Landmark requesting information about: "
<< region_id << LL_ENDL;
msg->newMessage("RegionHandleRequest");
msg->nextBlock("RequestBlock");
@@ -214,7 +258,7 @@ void LLLandmark::requestRegionHandle(
else if(callback)
{
// we have the answer locally - just call the callack.
- LL_DEBUGS() << "requestRegionHandle: ready" << LL_ENDL;
+ LL_DEBUGS("Landmark") << "requestRegionHandle: ready" << LL_ENDL;
callback(region_id, (*it).second.mRegionHandle);
}
}
diff --git a/indra/llinventory/lllandmark.h b/indra/llinventory/lllandmark.h
index 92923ea6fb..be34113a90 100644
--- a/indra/llinventory/lllandmark.h
+++ b/indra/llinventory/lllandmark.h
@@ -60,7 +60,7 @@ public:
// constructs a new LLLandmark from a string
// return NULL if there's an error
- static LLLandmark* constructFromString(const char *buffer);
+ static LLLandmark* constructFromString(const char *buffer, const S32 buffer_size);
// register callbacks that this class handles
static void registerCallbacks(LLMessageSystem* msg);
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
index 61b59e35aa..8a8e2bb340 100644
--- a/indra/llinventory/llsettingsbase.cpp
+++ b/indra/llinventory/llsettingsbase.cpp
@@ -395,7 +395,7 @@ bool LLSettingsBase::validate()
LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &validations, bool partial)
{
- static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, 63));
+ static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, _2, 63));
static Validator validateId(SETTING_ID, false, LLSD::TypeUUID);
static Validator validateHash(SETTING_HASH, false, LLSD::TypeInteger);
static Validator validateType(SETTING_TYPE, false, LLSD::TypeString);
@@ -534,7 +534,7 @@ bool LLSettingsBase::Validator::verify(LLSD &data, U32 flags)
return false;
}
- if (!mVerify.empty() && !mVerify(data[mName]))
+ if (!mVerify.empty() && !mVerify(data[mName], flags))
{
LL_WARNS("SETTINGS") << "Setting '" << mName << "' fails validation." << LL_ENDL;
return false;
@@ -543,17 +543,17 @@ bool LLSettingsBase::Validator::verify(LLSD &data, U32 flags)
return true;
}
-bool LLSettingsBase::Validator::verifyColor(LLSD &value)
+bool LLSettingsBase::Validator::verifyColor(LLSD &value, U32)
{
return (value.size() == 3 || value.size() == 4);
}
-bool LLSettingsBase::Validator::verifyVector(LLSD &value, S32 length)
+bool LLSettingsBase::Validator::verifyVector(LLSD &value, U32, S32 length)
{
return (value.size() == length);
}
-bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length)
+bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, U32, S32 length)
{
if (value.size() != length)
return false;
@@ -596,7 +596,7 @@ bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length)
return true;
}
-bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals)
+bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, U32, LLSD minvals, LLSD maxvals)
{
for (S32 index = 0; index < value.size(); ++index)
{
@@ -619,12 +619,12 @@ bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LL
return true;
}
-bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value)
+bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value, U32)
{
return (value.size() == 4);
}
-bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value)
+bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value, U32)
{
if (value.size() != 4)
return false;
@@ -642,7 +642,7 @@ bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value)
return true;
}
-bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range)
+bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, U32, LLSD range)
{
F64 real = value.asReal();
@@ -655,7 +655,7 @@ bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range)
return true;
}
-bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range)
+bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, U32, LLSD range)
{
S32 ival = value.asInteger();
@@ -668,7 +668,7 @@ bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range)
return true;
}
-bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, S32 length)
+bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, U32, S32 length)
{
std::string sval = value.asString();
diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h
index f7a9d5b7cd..1f0589f571 100644
--- a/indra/llinventory/llsettingsbase.h
+++ b/indra/llinventory/llsettingsbase.h
@@ -270,7 +270,7 @@ public:
public:
static const U32 VALIDATION_PARTIAL;
- typedef boost::function<bool(LLSD &)> verify_pr;
+ typedef boost::function<bool(LLSD &, U32)> verify_pr;
Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr(), LLSD defval = LLSD()) :
mName(name),
@@ -287,15 +287,15 @@ public:
bool verify(LLSD &data, U32 flags);
// Some basic verifications
- static bool verifyColor(LLSD &value);
- static bool verifyVector(LLSD &value, S32 length);
- static bool verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals);
- static bool verifyVectorNormalized(LLSD &value, S32 length);
- static bool verifyQuaternion(LLSD &value);
- static bool verifyQuaternionNormal(LLSD &value);
- static bool verifyFloatRange(LLSD &value, LLSD range);
- static bool verifyIntegerRange(LLSD &value, LLSD range);
- static bool verifyStringLength(LLSD &value, S32 length);
+ static bool verifyColor(LLSD &value, U32 flags);
+ static bool verifyVector(LLSD &value, U32 flags, S32 length);
+ static bool verifyVectorMinMax(LLSD &value, U32 flags, LLSD minvals, LLSD maxvals);
+ static bool verifyVectorNormalized(LLSD &value, U32 flags, S32 length);
+ static bool verifyQuaternion(LLSD &value, U32 flags);
+ static bool verifyQuaternionNormal(LLSD &value, U32 flags);
+ static bool verifyFloatRange(LLSD &value, U32 flags, LLSD range);
+ static bool verifyIntegerRange(LLSD &value, U32 flags, LLSD range);
+ static bool verifyStringLength(LLSD &value, U32 flags, S32 length);
private:
std::string mName;
diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp
index a687fd840d..2bb03e8391 100644
--- a/indra/llinventory/llsettingsdaycycle.cpp
+++ b/indra/llinventory/llsettingsdaycycle.cpp
@@ -460,7 +460,7 @@ void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F64 mix)
namespace
{
- bool validateDayCycleTrack(LLSD &value)
+ bool validateDayCycleTrack(LLSD &value, U32 flags)
{
// Trim extra tracks.
while (value.size() > LLSettingsDay::TRACK_MAX)
@@ -531,7 +531,7 @@ namespace
return true;
}
- bool validateDayCycleFrames(LLSD &value)
+ bool validateDayCycleFrames(LLSD &value, U32 flags)
{
bool hasSky(false);
bool hasWater(false);
@@ -544,7 +544,7 @@ namespace
if (ftype == "sky")
{
LLSettingsSky::validation_list_t valid_sky = LLSettingsSky::validationList();
- LLSD res_sky = LLSettingsBase::settingValidation(frame, valid_sky);
+ LLSD res_sky = LLSettingsBase::settingValidation(frame, valid_sky, flags);
if (res_sky["success"].asInteger() == 0)
{
@@ -557,7 +557,7 @@ namespace
else if (ftype == "water")
{
LLSettingsWater::validation_list_t valid_h2o = LLSettingsWater::validationList();
- LLSD res_h2o = LLSettingsBase::settingValidation(frame, valid_h2o);
+ LLSD res_h2o = LLSettingsBase::settingValidation(frame, valid_h2o, flags);
if (res_h2o["success"].asInteger() == 0)
{
LL_WARNS("SETTINGS") << "Water setting named '" << (*itf).first << "' validation failed!: " << res_h2o << LL_ENDL;
@@ -573,18 +573,20 @@ namespace
}
}
- if (!hasSky)
+ if ((flags & LLSettingsBase::Validator::VALIDATION_PARTIAL) == 0)
{
- LL_WARNS("SETTINGS") << "No skies defined." << LL_ENDL;
- return false;
- }
+ if (!hasSky)
+ {
+ LL_WARNS("SETTINGS") << "No skies defined." << LL_ENDL;
+ return false;
+ }
- if (!hasWater)
- {
- LL_WARNS("SETTINGS") << "No waters defined." << LL_ENDL;
- return false;
+ if (!hasWater)
+ {
+ LL_WARNS("SETTINGS") << "No waters defined." << LL_ENDL;
+ return false;
+ }
}
-
return true;
}
}
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 81937dbda5..1470edbf38 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -156,25 +156,25 @@ LLSettingsSky::validation_list_t legacyHazeValidationList()
if (legacyHazeValidation.empty())
{
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray,
- boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+ boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray,
- boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+ boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray,
- boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1,
+ boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(5.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(5.0f)))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(5.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(5.0f)))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0001f)(2.0f)))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0001f)(1000.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0001f)(1000.0f)))));
}
return legacyHazeValidation;
}
@@ -185,19 +185,19 @@ LLSettingsSky::validation_list_t rayleighValidationList()
if (rayleighValidation.empty())
{
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
}
return rayleighValidation;
}
@@ -208,19 +208,19 @@ LLSettingsSky::validation_list_t absorptionValidationList()
if (absorptionValidation.empty())
{
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
}
return absorptionValidation;
}
@@ -231,31 +231,31 @@ LLSettingsSky::validation_list_t mieValidationList()
if (mieValidation.empty())
{
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
}
return mieValidation;
}
-bool validateLegacyHaze(LLSD &value)
+bool validateLegacyHaze(LLSD &value, U32 flags)
{
LLSettingsSky::validation_list_t legacyHazeValidations = legacyHazeValidationList();
llassert(value.type() == LLSD::TypeMap);
- LLSD result = LLSettingsBase::settingValidation(value, legacyHazeValidations);
+ LLSD result = LLSettingsBase::settingValidation(value, legacyHazeValidations, flags);
if (result["errors"].size() > 0)
{
LL_WARNS("SETTINGS") << "Legacy Haze Config Validation errors: " << result["errors"] << LL_ENDL;
@@ -269,7 +269,7 @@ bool validateLegacyHaze(LLSD &value)
return true;
}
-bool validateRayleighLayers(LLSD &value)
+bool validateRayleighLayers(LLSD &value, U32 flags)
{
LLSettingsSky::validation_list_t rayleighValidations = rayleighValidationList();
if (value.isArray())
@@ -280,24 +280,24 @@ bool validateRayleighLayers(LLSD &value)
LLSD& layerConfig = (*itf);
if (layerConfig.type() == LLSD::TypeMap)
{
- if (!validateRayleighLayers(layerConfig))
+ if (!validateRayleighLayers(layerConfig, flags))
{
allGood = false;
}
}
else if (layerConfig.type() == LLSD::TypeArray)
{
- return validateRayleighLayers(layerConfig);
+ return validateRayleighLayers(layerConfig, flags);
}
else
{
- return LLSettingsBase::settingValidation(value, rayleighValidations);
+ return LLSettingsBase::settingValidation(value, rayleighValidations, flags);
}
}
return allGood;
}
llassert(value.type() == LLSD::TypeMap);
- LLSD result = LLSettingsBase::settingValidation(value, rayleighValidations);
+ LLSD result = LLSettingsBase::settingValidation(value, rayleighValidations, flags);
if (result["errors"].size() > 0)
{
LL_WARNS("SETTINGS") << "Rayleigh Config Validation errors: " << result["errors"] << LL_ENDL;
@@ -311,7 +311,7 @@ bool validateRayleighLayers(LLSD &value)
return true;
}
-bool validateAbsorptionLayers(LLSD &value)
+bool validateAbsorptionLayers(LLSD &value, U32 flags)
{
LLSettingsBase::validation_list_t absorptionValidations = absorptionValidationList();
if (value.isArray())
@@ -322,24 +322,24 @@ bool validateAbsorptionLayers(LLSD &value)
LLSD& layerConfig = (*itf);
if (layerConfig.type() == LLSD::TypeMap)
{
- if (!validateAbsorptionLayers(layerConfig))
+ if (!validateAbsorptionLayers(layerConfig, flags))
{
allGood = false;
}
}
else if (layerConfig.type() == LLSD::TypeArray)
{
- return validateAbsorptionLayers(layerConfig);
+ return validateAbsorptionLayers(layerConfig, flags);
}
else
{
- return LLSettingsBase::settingValidation(value, absorptionValidations);
+ return LLSettingsBase::settingValidation(value, absorptionValidations, flags);
}
}
return allGood;
}
llassert(value.type() == LLSD::TypeMap);
- LLSD result = LLSettingsBase::settingValidation(value, absorptionValidations);
+ LLSD result = LLSettingsBase::settingValidation(value, absorptionValidations, flags);
if (result["errors"].size() > 0)
{
LL_WARNS("SETTINGS") << "Absorption Config Validation errors: " << result["errors"] << LL_ENDL;
@@ -353,7 +353,7 @@ bool validateAbsorptionLayers(LLSD &value)
return true;
}
-bool validateMieLayers(LLSD &value)
+bool validateMieLayers(LLSD &value, U32 flags)
{
LLSettingsBase::validation_list_t mieValidations = mieValidationList();
if (value.isArray())
@@ -364,23 +364,23 @@ bool validateMieLayers(LLSD &value)
LLSD& layerConfig = (*itf);
if (layerConfig.type() == LLSD::TypeMap)
{
- if (!validateMieLayers(layerConfig))
+ if (!validateMieLayers(layerConfig, flags))
{
allGood = false;
}
}
else if (layerConfig.type() == LLSD::TypeArray)
{
- return validateMieLayers(layerConfig);
+ return validateMieLayers(layerConfig, flags);
}
else
{
- return LLSettingsBase::settingValidation(value, mieValidations);
+ return LLSettingsBase::settingValidation(value, mieValidations, flags);
}
}
return allGood;
}
- LLSD result = LLSettingsBase::settingValidation(value, mieValidations);
+ LLSD result = LLSettingsBase::settingValidation(value, mieValidations, flags);
if (result["errors"].size() > 0)
{
LL_WARNS("SETTINGS") << "Mie Config Validation errors: " << result["errors"] << LL_ENDL;
@@ -559,80 +559,80 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
validation.push_back(Validator(SETTING_HALO_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(1.0f)(1.0f)(3.0f)("*")))));
validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.001f)(3.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.001f)(3.0f)))));
validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(-50.0f)(-50.0f)),
LLSD(LLSDArray(50.0f)(50.0f)))));
validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(2000.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(2000.0f)))));
validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(20.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(20.0f)))));
validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.2f)("*")(-10.0f)("*")),
LLSD(LLSDArray(40.0f)("*")(10.0f)("*")))));
validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(10000.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(10000.0f)))));
validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
validation.push_back(Validator(SETTING_MOON_SCALE, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(500.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(500.0f)))));
validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
validation.push_back(Validator(SETTING_SUN_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
validation.push_back(Validator(SETTING_SUN_SCALE, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
validation.push_back(Validator(SETTING_SUN_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.1f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(0.1f)))));
validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(5.0f)(1000.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(5.0f)(1000.0f)))));
validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_RAYLEIGH_CONFIG, true, LLSD::TypeArray, &validateRayleighLayers));
validation.push_back(Validator(SETTING_ABSORPTION_CONFIG, true, LLSD::TypeArray, &validateAbsorptionLayers));
diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp
index 0eb95dcd89..1ae8d78b22 100644
--- a/indra/llinventory/llsettingswater.cpp
+++ b/indra/llinventory/llsettingswater.cpp
@@ -236,34 +236,34 @@ LLSettingsWater::validation_list_t LLSettingsWater::validationList()
// in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
validation.push_back(Validator(SETTING_BLUR_MULTIPLIER, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-0.5f)(0.5f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-0.5f)(0.5f)))));
validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f)))));
validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-10.0f)(10.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-10.0f)(10.0f)))));
validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(20.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(20.0f)))));
validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)),
LLSD(LLSDArray(10.0f)(10.0f)(10.0f)))));
validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(3.0f)))));
validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(3.0f)))));
validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
- boost::bind(&Validator::verifyVectorMinMax, _1,
+ boost::bind(&Validator::verifyVectorMinMax, _1, _2,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
}
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 999bee0a3f..552e820127 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -4,6 +4,7 @@ project(llmath)
include(00-Common)
include(LLCommon)
+include(bugsplat)
include(Boost)
include_directories(
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index 4d76dacdf7..be014e7b1e 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -138,13 +138,24 @@ LLCoprocedureManager::~LLCoprocedureManager()
close();
}
-LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::string &poolName)
+void LLCoprocedureManager::initializePool(const std::string &poolName)
{
+ poolMap_t::iterator it = mPoolMap.find(poolName);
+
+ if (it != mPoolMap.end())
+ {
+ // Pools are not supposed to be initialized twice
+ // Todo: ideally restrict init to STATE_FIRST
+ LL_ERRS() << "Pool is already present " << poolName << LL_ENDL;
+ return;
+ }
+
// Attempt to look up a pool size in the configuration. If found use that
std::string keyName = "PoolSize" + poolName;
int size = 0;
LL_ERRS_IF(poolName.empty(), "CoprocedureManager") << "Poolname must not be empty" << LL_ENDL;
+ LL_INFOS("CoprocedureManager") << "Initializing pool " << poolName << LL_ENDL;
if (mPropertyQueryFn)
{
@@ -171,8 +182,6 @@ LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::
bool inserted = mPoolMap.emplace(poolName, pool).second;
LL_ERRS_IF(!inserted, "CoprocedureManager") << "Unable to add pool named \"" << poolName << "\" to map. FATAL!" << LL_ENDL;
-
- return pool;
}
//-------------------------------------------------------------------------
@@ -182,20 +191,28 @@ LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const s
// not exist, create it.
poolMap_t::iterator it = mPoolMap.find(pool);
- poolPtr_t targetPool = (it != mPoolMap.end()) ? it->second : initializePool(pool);
+ if (it == mPoolMap.end())
+ {
+ // initializing pools in enqueueCoprocedure is not thread safe,
+ // at the moment pools need to be initialized manually
+ LL_ERRS() << "Uninitialized pool " << pool << LL_ENDL;
+ }
+ poolPtr_t targetPool = it->second;
return targetPool->enqueueCoprocedure(name, proc);
}
void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn)
{
// functions to discover and store the pool sizes
+ // Might be a better idea to make an initializePool(name, size) to init everything externally
mPropertyQueryFn = queryfn;
mPropertyDefineFn = updatefn;
- // workaround until we get mutex into initializePool
- initializePool("AssetStorage");
initializePool("Upload");
+ initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS
+ // "ExpCache" pool gets initialized in LLExperienceCache
+ // asset storage pool gets initialized in LLViewerAssetStorage
}
//-------------------------------------------------------------------------
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index d5557c129f..2d460826ff 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -79,6 +79,8 @@ public:
void close();
void close(const std::string &pool);
+
+ void initializePool(const std::string &poolName);
private:
@@ -87,8 +89,6 @@ private:
poolMap_t mPoolMap;
- poolPtr_t initializePool(const std::string &poolName);
-
SettingQuery_t mPropertyQueryFn;
SettingUpdate_t mPropertyDefineFn;
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 64c01bd9eb..db22ad2ea3 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -108,6 +108,8 @@ void LLExperienceCache::initSingleton()
cache_stream >> (*this);
}
+ LLCoprocedureManager::instance().initializePool("ExpCache");
+
LLCoros::instance().launch("LLExperienceCache::idleCoro",
boost::bind(&LLExperienceCache::idleCoro, this));
diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp
index 9db13a37b5..6424117ef3 100644
--- a/indra/llmessage/tests/llcoproceduremanager_test.cpp
+++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp
@@ -91,6 +91,7 @@ namespace tut
{
Sync sync;
int foo = 0;
+ LLCoprocedureManager::instance().initializePool("PoolName");
LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName",
[&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) {
sync.bump();
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 7d18bae947..e5b4dec1bd 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -154,9 +154,9 @@ void LLPluginProcessParent::shutdown()
{
EState state = (*it).second->mState;
if (state != STATE_CLEANUP
- || state != STATE_EXITING
- || state != STATE_DONE
- || state != STATE_ERROR)
+ && state != STATE_EXITING
+ && state != STATE_DONE
+ && state != STATE_ERROR)
{
(*it).second->setState(STATE_GOODBYE);
}
diff --git a/indra/llprimitive/llmediaentry.cpp b/indra/llprimitive/llmediaentry.cpp
index 02aba2bd83..53e9555c6a 100644
--- a/indra/llprimitive/llmediaentry.cpp
+++ b/indra/llprimitive/llmediaentry.cpp
@@ -27,8 +27,7 @@
#include "linden_common.h"
#include "llmediaentry.h"
#include "lllslconstants.h"
-
-#include <boost/regex.hpp>
+#include "llregex.h"
// LLSD key defines
// DO NOT REORDER OR REMOVE THESE!
@@ -456,7 +455,7 @@ static bool pattern_match(const std::string &candidate_str, const std::string &p
// case-insensitive matching:
boost::regex regexp(expression, boost::regex::perl|boost::regex::icase);
- return boost::regex_match(candidate_str, regexp);
+ return ll_regex_match(candidate_str, regexp);
}
bool LLMediaEntry::checkCandidateUrl(const std::string& url) const
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index d515fc707a..03b6aac20c 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -50,6 +50,7 @@ U32 LLRender::sUIVerts = 0;
U32 LLTexUnit::sWhiteTexture = 0;
bool LLRender::sGLCoreProfile = false;
bool LLRender::sNsightDebugSupport = false;
+LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 41f4fe4017..af8568f8a3 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -463,6 +463,7 @@ public:
static U32 sUIVerts;
static bool sGLCoreProfile;
static bool sNsightDebugSupport;
+ static LLVector2 sUIGLScaleFactor;
private:
friend class LLLightState;
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index 801b945806..dd34f3e383 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -106,11 +106,10 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe
top += LLFontGL::sCurOrigin.mY;
gGL.loadUIIdentity();
- LLRender2D *r2d_inst = LLRender2D::getInstance();
- gl_rect_2d(llfloor((F32)left * r2d_inst->mGLScaleFactor.mV[VX]) - pixel_offset,
- llfloor((F32)top * r2d_inst->mGLScaleFactor.mV[VY]) + pixel_offset,
- llfloor((F32)right * r2d_inst->mGLScaleFactor.mV[VX]) + pixel_offset,
- llfloor((F32)bottom * r2d_inst->mGLScaleFactor.mV[VY]) - pixel_offset,
+ gl_rect_2d(llfloor((F32)left * LLRender::sUIGLScaleFactor.mV[VX]) - pixel_offset,
+ llfloor((F32)top * LLRender::sUIGLScaleFactor.mV[VY]) + pixel_offset,
+ llfloor((F32)right * LLRender::sUIGLScaleFactor.mV[VX]) + pixel_offset,
+ llfloor((F32)bottom * LLRender::sUIGLScaleFactor.mV[VY]) - pixel_offset,
filled);
gGL.popUIMatrix();
}
@@ -1568,7 +1567,6 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
LLRender2D::LLRender2D(LLImageProviderInterface* image_provider)
{
- mGLScaleFactor = LLVector2(1.f, 1.f);
mImageProvider = image_provider;
if(mImageProvider)
{
@@ -1585,7 +1583,7 @@ LLRender2D::~LLRender2D()
}
}
-
+// static
void LLRender2D::translate(F32 x, F32 y, F32 z)
{
gGL.translateUI(x,y,z);
@@ -1594,12 +1592,14 @@ void LLRender2D::translate(F32 x, F32 y, F32 z)
LLFontGL::sCurDepth += z;
}
+// static
void LLRender2D::pushMatrix()
{
gGL.pushUIMatrix();
LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
}
+// static
void LLRender2D::popMatrix()
{
gGL.popUIMatrix();
@@ -1608,6 +1608,7 @@ void LLRender2D::popMatrix()
LLFontGL::sOriginStack.pop_back();
}
+// static
void LLRender2D::loadIdentity()
{
gGL.loadUIIdentity();
@@ -1616,15 +1617,11 @@ void LLRender2D::loadIdentity()
LLFontGL::sCurDepth = 0.f;
}
-void LLRender2D::setScaleFactor(const LLVector2 &scale_factor)
-{
- mGLScaleFactor = scale_factor;
-}
-
+// static
void LLRender2D::setLineWidth(F32 width)
{
gGL.flush();
- glLineWidth(width * lerp(mGLScaleFactor.mV[VX], mGLScaleFactor.mV[VY], 0.5f));
+ glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
}
LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
index 8c01784071..206e68f084 100644
--- a/indra/llrender/llrender2dutils.h
+++ b/indra/llrender/llrender2dutils.h
@@ -128,19 +128,16 @@ class LLRender2D : public LLParamSingleton<LLRender2D>
LOG_CLASS(LLRender2D);
~LLRender2D();
public:
- void pushMatrix();
- void popMatrix();
- void loadIdentity();
- void translate(F32 x, F32 y, F32 z = 0.0f);
+ static void pushMatrix();
+ static void popMatrix();
+ static void loadIdentity();
+ static void translate(F32 x, F32 y, F32 z = 0.0f);
- void setLineWidth(F32 width);
- void setScaleFactor(const LLVector2& scale_factor);
+ static void setLineWidth(F32 width);
LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
- LLVector2 mGLScaleFactor;
-
protected:
// since LLRender2D has no control of image provider's lifecycle
// we need a way to tell LLRender2D that provider died and
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 098621b543..04485c6262 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -1006,7 +1006,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
LLRect screen_rect;
localRectToScreen(child->getRect(),&screen_rect);
- if ( root_rect.overlaps(screen_rect) && LLUI::getInstance()->mDirtyRect.overlaps(screen_rect))
+ if ( root_rect.overlaps(screen_rect) && sDirtyRect.overlaps(screen_rect))
{
gGL.matrixMode(LLRender::MM_MODELVIEW);
LLUI::pushMatrix();
diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp
index 7817d99aef..8fc2978bdd 100644
--- a/indra/llui/llconsole.cpp
+++ b/indra/llui/llconsole.cpp
@@ -180,7 +180,9 @@ void LLConsole::draw()
LLUIImagePtr imagep = LLUI::getUIImage("transparent");
- F32 console_opacity = llclamp(LLUI::getInstance()->mSettingGroups["config"]->getF32("ConsoleBackgroundOpacity"), 0.f, 1.f);
+ static LLCachedControl<F32> console_bg_opacity(*LLUI::getInstance()->mSettingGroups["config"], "ConsoleBackgroundOpacity", 0.7f);
+ F32 console_opacity = llclamp(console_bg_opacity(), 0.f, 1.f);
+
LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground");
color.mV[VALPHA] *= console_opacity;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 8ceb411ede..0e42922543 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -381,13 +381,15 @@ void LLFloater::layoutDragHandle()
// static
void LLFloater::updateActiveFloaterTransparency()
{
- sActiveControlTransparency = LLUI::getInstance()->mSettingGroups["config"]->getF32("ActiveFloaterTransparency");
+ static LLCachedControl<F32> active_transparency(*LLUI::getInstance()->mSettingGroups["config"], "ActiveFloaterTransparency", 1.f);
+ sActiveControlTransparency = active_transparency;
}
// static
void LLFloater::updateInactiveFloaterTransparency()
{
- sInactiveControlTransparency = LLUI::getInstance()->mSettingGroups["config"]->getF32("InactiveFloaterTransparency");
+ static LLCachedControl<F32> inactive_transparency(*LLUI::getInstance()->mSettingGroups["config"], "InactiveFloaterTransparency", 0.95f);
+ sInactiveControlTransparency = inactive_transparency;
}
void LLFloater::addResizeCtrls()
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 0c1dcc301b..622c9edba7 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -342,9 +342,9 @@ static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
void LLFolderView::filter( LLFolderViewFilter& filter )
{
LL_RECORD_BLOCK_TIME(FTM_FILTER);
- static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
- static LLCachedControl<S32> filter_hidden(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
- filter.resetTime(llclamp(mParentPanel.get()->getVisible() ? filter_visible() : filter_hidden(), 1, 100));
+ static LLCachedControl<S32> time_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
+ static LLCachedControl<S32> time_invisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
+ filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? time_visible() : time_invisible()), 1, 100));
// Note: we filter the model, not the view
getViewModelItem()->filter(filter);
@@ -663,7 +663,8 @@ void LLFolderView::draw()
closeAutoOpenedFolders();
}
- if (mSearchTimer.getElapsedTimeF32() > LLUI::getInstance()->mSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size())
+ static LLCachedControl<F32> type_ahead_timeout(*LLUI::getInstance()->mSettingGroups["config"], "TypeAheadTimeout", 1.5f);
+ if (mSearchTimer.getElapsedTimeF32() > type_ahead_timeout || !mSearchString.size())
{
mSearchString.clear();
}
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 1c6c7b1b35..285bf9f484 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -962,9 +962,10 @@ void LLFolderViewItem::draw()
//
if (filter_string_length > 0)
{
- F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
+ S32 filter_offset = mViewModelItem->getFilterStringOffset();
+ F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string, filter_offset, filter_string_length);
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
- font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
+ font->renderUTF8( combined_string, filter_offset, match_string_left, yy,
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
filter_string_length, S32_MAX, &right_x, FALSE );
}
@@ -1607,7 +1608,7 @@ void LLFolderViewFolder::destroyView()
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
-void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
+void LLFolderViewFolder::extractItem( LLFolderViewItem* item, bool deparent_model )
{
if (item->isSelected())
getRoot()->clearSelection();
@@ -1630,7 +1631,11 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
mItems.erase(it);
}
//item has been removed, need to update filter
- getViewModelItem()->removeChild(item->getViewModelItem());
+ if (deparent_model)
+ {
+ // in some cases model does not belong to parent view, is shared between views
+ getViewModelItem()->removeChild(item->getViewModelItem());
+ }
//because an item is going away regardless of filter status, force rearrange
requestArrange();
removeChild(item);
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index da09d139e9..616d2e7d86 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -387,7 +387,7 @@ public:
// extractItem() removes the specified item from the folder, but
// doesn't delete it.
- virtual void extractItem( LLFolderViewItem* item );
+ virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);
// This function is called by a child that needs to be resorted.
void resort(LLFolderViewItem* item);
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index ea106b5fae..93122503d1 100644
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -48,9 +48,9 @@ std::string LLFolderViewModelCommon::getStatusText()
void LLFolderViewModelCommon::filter()
{
- static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
- getFilter().resetTime(llclamp(filter_visible(), 1, 100));
- mFolderView->getViewModelItem()->filter(getFilter());
+ static LLCachedControl<S32> max_time(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
+ getFilter().resetTime(llclamp(max_time(), 1, 100));
+ mFolderView->getViewModelItem()->filter(getFilter());
}
bool LLFolderViewModelItemCommon::hasFilterStringMatch()
diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp
index acfe4a0cba..f89064d59a 100644
--- a/indra/llui/llmultislider.cpp
+++ b/indra/llui/llmultislider.cpp
@@ -136,6 +136,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)
}
}
+ mRoundedSquareImgp = LLUI::getUIImage("Rounded_Square");
if (p.thumb_image.isProvided())
{
mThumbImagep = LLUI::getUIImage(p.thumb_image());
@@ -666,8 +667,6 @@ void LLMultiSlider::draw()
F32 opacity = getEnabled() ? 1.f : 0.3f;
// Track
- LLUIImagePtr thumb_imagep = LLUI::getUIImage("Rounded_Square");
-
static LLUICachedControl<S32> multi_track_height_width ("UIMultiTrackHeight", 0);
S32 height_offset = 0;
S32 width_offset = 0;
@@ -685,7 +684,7 @@ void LLMultiSlider::draw()
if(mDrawTrack)
{
track_rect.stretch(-1);
- thumb_imagep->draw(track_rect, mTrackColor.get() % opacity);
+ mRoundedSquareImgp->draw(track_rect, mTrackColor.get() % opacity);
}
// if we're supposed to use a drawn triangle
@@ -704,7 +703,7 @@ void LLMultiSlider::draw()
mTriangleColor.get() % opacity, TRUE);
}
}
- else if (!thumb_imagep && !mThumbImagep)
+ else if (!mRoundedSquareImgp && !mThumbImagep)
{
// draw all the thumbs
curSldrIt = mThumbRects.end();
@@ -757,7 +756,7 @@ void LLMultiSlider::draw()
}
else
{
- thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
+ mRoundedSquareImgp->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);
}
}
@@ -772,7 +771,7 @@ void LLMultiSlider::draw()
}
else
{
- thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
+ mRoundedSquareImgp->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
}
}
}
@@ -784,7 +783,7 @@ void LLMultiSlider::draw()
}
else
{
- thumb_imagep->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
+ mRoundedSquareImgp->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());
}
}
@@ -822,11 +821,11 @@ void LLMultiSlider::draw()
}
else if (capture == this)
{
- thumb_imagep->drawSolid(mIt->second, curThumbColor);
+ mRoundedSquareImgp->drawSolid(mIt->second, curThumbColor);
}
else
{
- thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity);
+ mRoundedSquareImgp->drawSolid(mIt->second, curThumbColor % opacity);
}
}
@@ -846,11 +845,11 @@ void LLMultiSlider::draw()
}
else if (capture == this)
{
- thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
+ mRoundedSquareImgp->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());
}
else
{
- thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
+ mRoundedSquareImgp->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);
}
}
if(hoverSldrIt != mThumbRects.end())
@@ -861,7 +860,7 @@ void LLMultiSlider::draw()
}
else
{
- thumb_imagep->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get());
+ mRoundedSquareImgp->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get());
}
}
}
diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h
index 99a78d6e09..3cb4b760b0 100644
--- a/indra/llui/llmultislider.h
+++ b/indra/llui/llmultislider.h
@@ -150,6 +150,7 @@ protected:
LLUIColor mDisabledThumbColor;
LLUIColor mTriangleColor;
LLUIImagePtr mThumbImagep; //blimps on the slider, for now no 'disabled' support
+ LLUIImagePtr mRoundedSquareImgp; //blimps on the slider, for now no 'disabled' support
const EOrientation mOrientation;
diff --git a/indra/llui/llnotificationptr.h b/indra/llui/llnotificationptr.h
index acc047527f..580f353c7d 100644
--- a/indra/llui/llnotificationptr.h
+++ b/indra/llui/llnotificationptr.h
@@ -27,9 +27,8 @@
// Many classes just store a single LLNotificationPtr
// and llnotifications.h is very large, so define this ligher header.
-#include <boost/shared_ptr.hpp>
class LLNotification;
-typedef boost::shared_ptr<LLNotification> LLNotificationPtr;
+typedef std::shared_ptr<LLNotification> LLNotificationPtr;
#endif
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index b0b56cf599..b1123d27e5 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -85,7 +85,6 @@
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
#include <boost/type_traits.hpp>
#include <boost/signals2.hpp>
#include <boost/range.hpp>
@@ -305,7 +304,7 @@ typedef boost::shared_ptr<LLNotificationVisibilityRule> LLNotificationVisibility
*/
class LLNotification :
boost::noncopyable,
- public boost::enable_shared_from_this<LLNotification>
+ public std::enable_shared_from_this<LLNotification>
{
LOG_CLASS(LLNotification);
friend class LLNotifications;
@@ -744,7 +743,10 @@ public:
: mFilter(filter),
mItems()
{}
- virtual ~LLNotificationChannelBase() {}
+ virtual ~LLNotificationChannelBase()
+ {
+ mItems.clear();
+ }
// you can also connect to a Channel, so you can be notified of
// changes to this channel
LLBoundListener connectChanged(const LLEventListener& slot)
@@ -874,6 +876,7 @@ class LLNotifications :
{
LLSINGLETON(LLNotifications);
LOG_CLASS(LLNotifications);
+ virtual ~LLNotifications() {}
public:
@@ -1071,7 +1074,11 @@ public:
LLPersistentNotificationChannel()
: LLNotificationChannel("Persistent", "Visible", &notificationFilter)
{}
- virtual ~LLPersistentNotificationChannel() {}
+
+ virtual ~LLPersistentNotificationChannel()
+ {
+ mHistory.clear();
+ }
typedef std::vector<LLNotificationPtr> history_list_t;
history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); }
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
index cc9ff7a487..82b0415624 100644
--- a/indra/llui/llscrolllistcolumn.cpp
+++ b/indra/llui/llscrolllistcolumn.cpp
@@ -257,7 +257,7 @@ void LLScrollColumnHeader::updateResizeBars()
for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
{
LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
- if (columnp->mHeader && columnp->mHeader->canResize())
+ if (columnp && columnp->mHeader && columnp->mHeader->canResize())
{
num_resizable_columns++;
}
@@ -269,7 +269,7 @@ void LLScrollColumnHeader::updateResizeBars()
for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
{
LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
- if (!columnp->mHeader) continue;
+ if (!columnp || !columnp->mHeader) continue;
BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
columnp->mHeader->enableResizeBar(enable);
if (enable)
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index be85f1cb6a..de644185fd 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -743,12 +743,12 @@ void LLScrollListCtrl::updateColumns(bool force_update)
LLScrollColumnHeader* last_header = NULL;
for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it)
{
- if ((*column_ordered_it)->getWidth() < 0)
+ LLScrollListColumn* column = *column_ordered_it;
+ if (!column || column->getWidth() < 0)
{
// skip hidden columns
continue;
}
- LLScrollListColumn* column = *column_ordered_it;
if (column->mHeader)
{
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 4868c66d1b..5150df25f2 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -1129,7 +1129,7 @@ BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)
BOOL handled = FALSE;
S32 mouse_distance_squared = (x - mMouseDownX) * (x - mMouseDownX) + (y - mMouseDownY) * (y - mMouseDownY);
- S32 drag_threshold = LLUI::getInstance()->mSettingGroups["config"]->getS32("DragAndDropDistanceThreshold");
+ static LLCachedControl<S32> drag_threshold(*LLUI::getInstance()->mSettingGroups["config"], "DragAndDropDistanceThreshold", 3);
if (mouse_distance_squared > drag_threshold * drag_threshold
&& hasMouseCapture() &&
mStartDragItemCallback && mHandleDragItemCallback)
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index 422534b781..2f56a8b1d0 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -358,8 +358,8 @@ void LLToolTip::draw()
if (mFadeTimer.getStarted())
{
- F32 tool_tip_fade_time = LLUI::getInstance()->mSettingGroups["config"]->getF32("ToolTipFadeTime");
- alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, 1.f, 0.f);
+ static LLCachedControl<F32> tool_tip_fade_time(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFadeTime", 0.2f);
+ alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time(), 1.f, 0.f);
if (alpha == 0.f)
{
// finished fading out, so hide ourselves
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 656b69d3ed..6f16745bd3 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -154,7 +154,6 @@ mAudioCallback(audio_callback),
mDeferredAudioCallback(deferred_audio_callback),
mWindow(NULL), // set later in startup
mRootView(NULL),
-mDirty(FALSE),
mHelpImpl(NULL)
{
LLRender2D::initParamSingleton(image_provider);
@@ -203,19 +202,6 @@ void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& rem
mClearPopupsFunc = clear_popups;
}
-void LLUI::dirtyRect(LLRect rect)
-{
- if (!mDirty)
- {
- mDirtyRect = rect;
- mDirty = TRUE;
- }
- else
- {
- mDirtyRect.unionWith(rect);
- }
-}
-
void LLUI::setMousePositionScreen(S32 x, S32 y)
{
#if defined(LL_DARWIN)
@@ -510,6 +496,18 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
return context;
}
+//static
+LLVector2& LLUI::getScaleFactor()
+{
+ return LLRender::sUIGLScaleFactor;
+}
+
+//static
+void LLUI::setScaleFactor(const LLVector2& scale_factor)
+{
+ LLRender::sUIGLScaleFactor = scale_factor;
+}
+
// LLLocalClipRect and LLScreenClipRect moved to lllocalcliprect.h/cpp
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 9856e551cc..30dbd7248f 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -245,10 +245,6 @@ public:
void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
- LLRect mDirtyRect;
- BOOL mDirty;
- void dirtyRect(LLRect rect);
-
// Return the ISO639 language name ("en", "ko", etc.) for the viewer UI.
// http://www.loc.gov/standards/iso639-2/php/code_list.php
std::string getUILanguage();
@@ -313,14 +309,14 @@ public:
void positionViewNearMouse(LLView* view, S32 spawn_x = S32_MAX, S32 spawn_y = S32_MAX);
// LLRender2D wrappers
- static void pushMatrix() { LLRender2D::getInstance()->pushMatrix(); }
- static void popMatrix() { LLRender2D::getInstance()->popMatrix(); }
- static void loadIdentity() { LLRender2D::getInstance()->loadIdentity(); }
- static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::getInstance()->translate(x, y, z); }
-
- static LLVector2& getScaleFactor() { return LLRender2D::getInstance()->mGLScaleFactor; }
- static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::getInstance()->setScaleFactor(scale_factor); }
- static void setLineWidth(F32 width) { LLRender2D::getInstance()->setLineWidth(width); }
+ static void pushMatrix() { LLRender2D::pushMatrix(); }
+ static void popMatrix() { LLRender2D::popMatrix(); }
+ static void loadIdentity() { LLRender2D::loadIdentity(); }
+ static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
+
+ static LLVector2& getScaleFactor();
+ static void setScaleFactor(const LLVector2& scale_factor);
+ static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }
static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)
{ return LLRender2D::getInstance()->getUIImageByID(image_id, priority); }
static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 20dda54771..557d6f45ff 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -35,6 +35,7 @@
#include "llavatarnamecache.h"
#include "llcachename.h"
+#include "llregex.h"
#include "lltrans.h"
#include "lluicolortable.h"
#include "message.h"
@@ -176,7 +177,7 @@ void LLUrlEntryBase::callObservers(const std::string &id,
bool LLUrlEntryBase::isLinkDisabled() const
{
// this allows us to have a global setting to turn off text hyperlink highlighting/action
- bool globally_disabled = LLUI::getInstance()->mSettingGroups["config"]->getBOOL("DisableTextHyperlinkActions");
+ static LLCachedControl<bool> globally_disabled(*LLUI::getInstance()->mSettingGroups["config"], "DisableTextHyperlinkActions", false);
return globally_disabled;
}
@@ -464,7 +465,9 @@ LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
"|"
"(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?)"
"|"
- "(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?))"
+ "(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?)"
+ "|"
+ "(https?://([-\\w\\.]*\\.)?secondlife\\.io(:\\d{1,5})?))"
"\\/\\S*",
boost::regex::perl|boost::regex::icase);
@@ -1127,7 +1130,7 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const
//
LLUrlEntryRegion::LLUrlEntryRegion()
{
- mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?",
+ mPattern = boost::regex("secondlife:///app/region/[A-Za-z0-9()_%]+(/\\d+)?(/\\d+)?(/\\d+)?/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL");
@@ -1414,7 +1417,7 @@ std::string LLUrlEntryIcon::getIcon(const std::string &url)
// Grep icon info between <icon>...</icon> tags
// matches[1] contains the icon name/path
boost::match_results<std::string::const_iterator> matches;
- mIcon = (boost::regex_match(url, matches, mPattern) && matches[1].matched)
+ mIcon = (ll_regex_match(url, matches, mPattern) && matches[1].matched)
? matches[1]
: LLStringUtil::null;
LLStringUtil::trim(mIcon);
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 321a0ec5b9..bfcd970529 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -26,10 +26,10 @@
*/
#include "linden_common.h"
+#include "llregex.h"
#include "llurlregistry.h"
#include "lluriparser.h"
-#include <boost/regex.hpp>
// default dummy callback that ignores any label updates from the server
void LLUrlRegistryNullCallback(const std::string &url, const std::string &label, const std::string& icon)
@@ -108,15 +108,7 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en
boost::cmatch result;
bool found;
- // regex_search can potentially throw an exception, so check for it
- try
- {
- found = boost::regex_search(text, result, regex);
- }
- catch (std::runtime_error &)
- {
- return false;
- }
+ found = ll_regex_search(text, result, regex);
if (! found)
{
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index cd47e2ecea..b942be2a4a 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -60,6 +60,8 @@ static const S32 LINE_HEIGHT = 15;
S32 LLView::sDepth = 0;
bool LLView::sDebugRects = false;
+bool LLView::sIsRectDirty = false;
+LLRect LLView::sDirtyRect;
bool LLView::sDebugRectsShowNames = true;
bool LLView::sDebugKeys = false;
bool LLView::sDebugMouseHandling = false;
@@ -885,14 +887,16 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
std::string tooltip = getToolTip();
if (!tooltip.empty())
{
+ static LLCachedControl<F32> tooltip_fast_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFastDelay", 0.1f);
+ static LLCachedControl<F32> tooltip_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipDelay", 0.7f);
+ static LLCachedControl<bool> allow_ui_tooltips(*LLUI::getInstance()->mSettingGroups["config"], "BasicUITooltips", true);
// allow "scrubbing" over ui by showing next tooltip immediately
// if previous one was still visible
F32 timeout = LLToolTipMgr::instance().toolTipVisible()
- ? LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipFastDelay" )
- : LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipDelay" );
+ ? tooltip_fast_delay
+ : tooltip_delay;
// Even if we don't show tooltips, consume the event, nothing below should show tooltip
- bool allow_ui_tooltips = LLUI::getInstance()->mSettingGroups["config"]->getBOOL("BasicUITooltips");
if (allow_ui_tooltips)
{
LLToolTipMgr::instance().show(LLToolTip::Params()
@@ -1189,7 +1193,7 @@ void LLView::drawChildren()
if (viewp->getVisible() && viewp->getRect().isValid())
{
LLRect screen_rect = viewp->calcScreenRect();
- if ( rootp->getLocalRect().overlaps(screen_rect) && LLUI::getInstance()->mDirtyRect.overlaps(screen_rect))
+ if ( rootp->getLocalRect().overlaps(screen_rect) && sDirtyRect.overlaps(screen_rect))
{
LLUI::pushMatrix();
{
@@ -1231,7 +1235,15 @@ void LLView::dirtyRect()
parent = parent->getParent();
}
- LLUI::getInstance()->dirtyRect(cur->calcScreenRect());
+ if (!sIsRectDirty)
+ {
+ sDirtyRect = cur->calcScreenRect();
+ sIsRectDirty = true;
+ }
+ else
+ {
+ sDirtyRect.unionWith(cur->calcScreenRect());
+ }
}
//Draw a box for debugging.
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 5c91c37d3c..c60dcf3344 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -657,6 +657,9 @@ public:
// Draw debug rectangles around widgets to help with alignment and spacing
static bool sDebugRects;
+ static bool sIsRectDirty;
+ static LLRect sDirtyRect;
+
// Draw widget names and sizes when drawing debug rectangles, turning this
// off is useful to make the rectangles themselves easier to see.
static bool sDebugRectsShowNames;
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 4a4fdb72e3..1a474cca90 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -739,11 +739,6 @@ namespace tut
"XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX",
"secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30");
- // DEV-35459: SLURLs and teleport Links not parsed properly
- testRegex("Region with quote", url,
- "XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX",
- "secondlife:///app/region/A%27ksha%20Oasis/41/166/701");
-
// Rendering tests.
testLabel("Render /app/region/Ahern/50/50/50/", url,
"secondlife:///app/region/Ahern/50/50/50/",
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 9e9abbadff..02e6b8c743 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -337,6 +337,11 @@ const std::string &LLDir::getDumpDir() const
return LLDir::sDumpDir;
}
+bool LLDir::dumpDirExists() const
+{
+ return !sDumpDir.empty();
+}
+
const std::string &LLDir::getPerAccountChatLogsDir() const
{
return mPerAccountChatLogsDir;
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 4988b9c6e3..0d027ec96a 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -90,6 +90,7 @@ class LLDir
const std::string &getLindenUserDir() const; // Location of the Linden user dir.
const std::string &getChatLogsDir() const; // Location of the chat logs dir.
const std::string &getDumpDir() const; // Location of the per-run dump dir.
+ bool dumpDirExists() const;
const std::string &getPerAccountChatLogsDir() const; // Location of the per account chat logs dir.
const std::string &getTempDir() const; // Common temporary directory
const std::string getCacheDir(bool get_default = false) const; // Location of the cache.
diff --git a/indra/llvfs/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp
index 3eb64e69d9..f57bf4ebc6 100644
--- a/indra/llvfs/lldiriterator.cpp
+++ b/indra/llvfs/lldiriterator.cpp
@@ -27,8 +27,8 @@
#include "lldiriterator.h"
#include "fix_macros.h"
+#include "llregex.h"
#include <boost/filesystem.hpp>
-#include <boost/regex.hpp>
namespace fs = boost::filesystem;
@@ -131,7 +131,7 @@ bool LLDirIterator::Impl::next(std::string &fname)
{
boost::smatch match;
std::string name = mIter->path().filename().string();
- found = boost::regex_match(name, match, mFilterExp);
+ found = ll_regex_match(name, match, mFilterExp);
if (found)
{
fname = name;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index d2c5b11c3d..f9b387b00b 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -494,7 +494,8 @@ attributedStringInfo getSegments(NSAttributedString *str)
// e.g. OS Window for upload something or Input Window...
// mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit)
mModifiers = [theEvent modifierFlags];
- bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers);
+
+ bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, [[theEvent characters] characterAtIndex:0]);
unichar ch;
if (acceptsText &&
!mMarkedTextAllowed &&
@@ -537,7 +538,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
if (mModifiers & mask)
{
eventData.mKeyEvent = NativeKeyEventData::KEYDOWN;
- callKeyDown(&eventData, [theEvent keyCode], 0);
+ callKeyDown(&eventData, [theEvent keyCode], 0, [[theEvent characters] characterAtIndex:0]);
}
else
{
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 44fd4127ce..43edc0110d 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -131,7 +131,7 @@ void setupInputWindow(NSWindowRef window, GLViewRef view);
// These are all implemented in llwindowmacosx.cpp.
// This is largely for easier interop between Obj-C and C++ (at least in the viewer's case due to the BOOL vs. BOOL conflict)
bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask);
-bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask);
+bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask, wchar_t character);
void callResetKeys();
bool callUnicodeCallback(wchar_t character, unsigned int mask);
void callRightMouseDown(float *pos, unsigned int mask);
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 0d0607a0bb..dfdfe4aa33 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -208,8 +208,17 @@ bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask)
return retVal;
}
-bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask)
+bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask, wchar_t character)
{
+ if((key == gKeyboard->inverseTranslateKey('Z')) && (character == 'y'))
+ {
+ key = gKeyboard->inverseTranslateKey('Y');
+ }
+ else if ((key == gKeyboard->inverseTranslateKey('Y')) && (character == 'z'))
+ {
+ key = gKeyboard->inverseTranslateKey('Z');
+ }
+
mRawKeyEvent = event;
bool retVal = gKeyboard->handleKeyDown(key, mask);
mRawKeyEvent = NULL;
diff --git a/indra/mac_crash_logger/README.txt b/indra/mac_crash_logger/README.txt
new file mode 100644
index 0000000000..6932a8d9c3
--- /dev/null
+++ b/indra/mac_crash_logger/README.txt
@@ -0,0 +1,3 @@
+This component is no longer used in Linden Lab builds.
+Change requests to support continued use by open source
+builds are welcome.
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 0bb62d79ff..8465285d2b 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -73,6 +73,7 @@ private:
void onCursorChangedCallback(dullahan::ECursorType type);
const std::vector<std::string> onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, const std::string dialog_accept_filter, bool& use_default);
bool onJSDialogCallback(const std::string origin_url, const std::string message_text, const std::string default_prompt_text);
+ bool onJSBeforeUnloadCallback();
void postDebugMessage(const std::string& msg);
void authResponse(LLPluginMessage &message);
@@ -377,6 +378,14 @@ bool MediaPluginCEF::onJSDialogCallback(const std::string origin_url, const std:
////////////////////////////////////////////////////////////////////////////////
//
+bool MediaPluginCEF::onJSBeforeUnloadCallback()
+{
+ // return true indicates we suppress the JavaScript UI entirely
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
{
std::string name = "";
@@ -523,10 +532,26 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
mCEFLib->setOnCursorChangedCallback(std::bind(&MediaPluginCEF::onCursorChangedCallback, this, std::placeholders::_1));
mCEFLib->setOnRequestExitCallback(std::bind(&MediaPluginCEF::onRequestExitCallback, this));
mCEFLib->setOnJSDialogCallback(std::bind(&MediaPluginCEF::onJSDialogCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+ mCEFLib->setOnJSBeforeUnloadCallback(std::bind(&MediaPluginCEF::onJSBeforeUnloadCallback, this));
dullahan::dullahan_settings settings;
+#if LL_WINDOWS
+ // As of CEF version 83+, for Windows versions, we need to tell CEF
+ // where the host helper process is since this DLL is not in the same
+ // dir as the executable that loaded it (SLPlugin.exe). The code in
+ // Dullahan that tried to figure out the location automatically uses
+ // the location of the exe which isn't helpful so we tell it explicitly.
+ char cur_dir_str[MAX_PATH];
+ GetCurrentDirectoryA(MAX_PATH, cur_dir_str);
+ settings.host_process_path = std::string(cur_dir_str);
+#endif
settings.accept_language_list = mHostLanguage;
- settings.background_color = 0xffffffff;
+
+ // SL-15560: Product team overruled my change to set the default
+ // embedded background color to match the floater background
+ // and set it to white
+ settings.background_color = 0xffffffff; // white
+
settings.cache_enabled = true;
settings.root_cache_path = mRootCachePath;
settings.cache_path = mCachePath;
@@ -537,7 +562,19 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
settings.disable_network_service = mDisableNetworkService;
settings.use_mock_keychain = mUseMockKeyChain;
#endif
- settings.flash_enabled = mPluginsEnabled;
+ // This setting applies to all plugins, not just Flash
+ // Regarding, SL-15559 PDF files do not load in CEF v91,
+ // it turns out that on Windows, PDF support is treated
+ // as a plugin on Windows only so turning all plugins
+ // off, disabled built in PDF support. (Works okay in
+ // macOS surprisingly). To mitigrate this, we set the global
+ // media enabled flag to whatever the consumer wants and
+ // explicitly disable Flash with a different setting (below)
+ settings.plugins_enabled = mPluginsEnabled;
+
+ // SL-14897 Disable Flash support in the embedded browser
+ settings.flash_enabled = false;
+
settings.flip_mouse_y = false;
settings.flip_pixels_y = true;
settings.frame_rate = 60;
@@ -546,8 +583,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
settings.initial_width = 1024;
settings.java_enabled = false;
settings.javascript_enabled = mJavascriptEnabled;
- settings.media_stream_enabled = false; // MAINT-6060 - WebRTC media removed until we can add granualrity/query UI
- settings.plugins_enabled = mPluginsEnabled;
+ settings.media_stream_enabled = false; // MAINT-6060 - WebRTC media removed until we can add granularity/query UI
+
settings.user_agent_substring = mCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
settings.webgl_enabled = true;
settings.log_file = mCefLogFile;
@@ -558,10 +595,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
mCEFLib->setCustomSchemes(custom_schemes);
bool result = mCEFLib->init(settings);
- if (!result)
- {
- // if this fails, the media system in viewer will put up a message
- }
+ if (!result)
+ {
+ // if this fails, the media system in viewer will put up a message
+ }
// now we can set page zoom factor
F32 factor = (F32)message_in.getValueReal("factor");
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 424fd17707..87caca56af 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -8,9 +8,7 @@ include(00-Common)
include(Linking)
include(Boost)
-if (BUGSPLAT_DB)
- include(bugsplat)
-endif (BUGSPLAT_DB)
+include(bugsplat)
include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
@@ -96,18 +94,18 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
-if (BUGSPLAT_DB)
- include_directories(
- ${BUGSPLAT_INCLUDE_DIR}
- )
-endif (BUGSPLAT_DB)
-
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLXML_SYSTEM_INCLUDE_DIRS}
${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
)
+if (USE_BUGSPLAT)
+ include_directories(AFTER
+ ${BUGSPLAT_INCLUDE_DIR}
+ )
+endif (USE_BUGSPLAT)
+
set(viewer_SOURCE_FILES
groupchatlistener.cpp
llaccountingcostmanager.cpp
@@ -1423,11 +1421,11 @@ if (DARWIN)
${COREAUDIO_LIBRARY}
)
- if (BUGSPLAT_DB)
+ if (USE_BUGSPLAT)
list(APPEND viewer_LIBRARIES
${BUGSPLAT_LIBRARIES}
)
- endif (BUGSPLAT_DB)
+ endif (USE_BUGSPLAT)
# Add resource files to the project.
set(viewer_RESOURCE_FILES
@@ -1765,10 +1763,10 @@ if (SDL_FOUND)
)
endif (SDL_FOUND)
-if (BUGSPLAT_DB)
+if (USE_BUGSPLAT)
set_property(TARGET ${VIEWER_BINARY_NAME}
- PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
-endif (BUGSPLAT_DB)
+ PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
+endif (USE_BUGSPLAT)
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
@@ -1847,9 +1845,12 @@ if (WINDOWS)
media_plugin_libvlc
media_plugin_example
winmm_shim
- windows-crash-logger
)
+ if (NOT USE_BUGSPLAT)
+ LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger)
+ endif (NOT USE_BUGSPLAT)
+
if (ADDRESS_SIZE EQUAL 64)
list(APPEND COPY_INPUT_DEPENDENCIES
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll
@@ -1912,10 +1913,11 @@ if (WINDOWS)
add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
- add_dependencies(${VIEWER_BINARY_NAME}
- SLPlugin
- windows-crash-logger
- )
+ add_dependencies(${VIEWER_BINARY_NAME} SLPlugin)
+
+ if (NOT USE_BUGSPLAT)
+ add_dependencies(${VIEWER_BINARY_NAME} windows-crash-logger)
+ endif (NOT USE_BUGSPLAT)
# sets the 'working directory' for debugging from visual studio.
# Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865)
@@ -2067,11 +2069,11 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLAPPEARANCE_LIBRARIES}
)
-if (BUGSPLAT_DB)
+if (USE_BUGSPLAT)
target_link_libraries(${VIEWER_BINARY_NAME}
${BUGSPLAT_LIBRARIES}
)
-endif (BUGSPLAT_DB)
+endif (USE_BUGSPLAT)
set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
"Path to artwork files.")
@@ -2082,13 +2084,16 @@ if (LINUX)
# These are the generated targets that are copied to package/
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
- linux-crash-logger
SLPlugin
media_plugin_gstreamer010
media_plugin_libvlc
llcommon
)
+ if (NOT USE_BUGSPLAT)
+ LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger)
+ endif (NOT USE_BUGSPLAT)
+
add_custom_command(
OUTPUT ${product}.tar.bz2
COMMAND ${PYTHON_EXECUTABLE}
@@ -2219,8 +2224,11 @@ if (DARWIN)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
)
- add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef mac-crash-logger)
- add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
+ add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef)
+
+ if (NOT USE_BUGSPLAT)
+ add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)
+ endif (NOT USE_BUGSPLAT)
if (ENABLE_SIGNING)
set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}")
@@ -2263,7 +2271,7 @@ endif (INSTALL)
# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
- if (NOT BUGSPLAT_DB)
+ if (NOT USE_BUGSPLAT)
# Breakpad symbol-file generation
set(SYMBOL_SEARCH_DIRS "")
if (WINDOWS)
@@ -2280,7 +2288,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
- set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
+ set(VIEWER_EXE_GLOBS "'${product}' SLPlugin")
set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
set(VIEWER_LIB_GLOB "*.dylib")
endif (DARWIN)
@@ -2318,7 +2326,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
endif (WINDOWS OR LINUX)
- else (NOT BUGSPLAT_DB)
+ else (NOT USE_BUGSPLAT)
# BugSplat symbol-file generation
if (WINDOWS)
# Just pack up a tarball containing only the .pdb file for the
@@ -2402,9 +2410,9 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
if (LINUX)
# TBD
endif (LINUX)
- endif (NOT BUGSPLAT_DB)
+ endif (NOT USE_BUGSPLAT)
- # for both BUGSPLAT_DB and Breakpad
+ # for both Bugsplat and Breakpad
add_dependencies(llpackage generate_symbols)
endif ()
@@ -2537,6 +2545,10 @@ if (LL_TESTS)
${BOOST_CONTEXT_LIBRARY}
)
+ LL_ADD_INTEGRATION_TEST(cppfeatures
+ ""
+ "${test_libs}"
+ )
LL_ADD_INTEGRATION_TEST(llsechandler_basic
llsechandler_basic.cpp
"${test_libs}"
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 22beed373e..4c8366c864 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.21
+6.4.23
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a2933b85a5..898c5a5273 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1584,10 +1584,11 @@
<key>Value</key>
<real>1.0</real>
</map>
- <key>CameraPreset</key> <!-- deprecated (see SL-12429) -->
+ <key>CameraPreset</key>
+ <!-- deprecated (see SL-12429) -->
<map>
<key>Comment</key>
- <string>Preset camera position - view (0 - rear, 1 - front, 2 - group)</string>
+ <string>(Deprecated) Preset camera position - view (0 - rear, 1 - front, 2 - group)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -2076,17 +2077,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>BrowserPluginsEnabled</key>
- <map>
- <key>Comment</key>
- <string>Enable Web plugins in the built-in Web browser?</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>ChatBarCustomWidth</key>
<map>
<key>Comment</key>
@@ -2505,10 +2495,11 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DEPRECATED: DebugShowPrivateMem</key> <!-- deprecated (see MAINT-8091) -->
+ <key>DebugShowPrivateMem</key>
+ <!-- deprecated (see MAINT-8091) -->
<map>
<key>Comment</key>
- <string>Show Private Mem Info</string>
+ <string>(Deprecated) Show Private Mem Info</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -5808,7 +5799,7 @@
<key>LoginSRVPump</key>
<map>
<key>Comment</key>
- <string>Name of the message pump that handles SRV request (deprecated)</string>
+ <string>(Deprecated) Name of the message pump that handles SRV request)</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
@@ -6619,10 +6610,11 @@
<key>Value</key>
<real>600.0</real>
</map>
- <key>MemoryPrivatePoolEnabled</key> <!-- deprecated (see MAINT-8091) -->
+ <key>MemoryPrivatePoolEnabled</key>
+ <!-- deprecated (see MAINT-8091) -->
<map>
<key>Comment</key>
- <string>DEPRECATED: Enable the private memory pool management</string>
+ <string>(Deprecated) Enable the private memory pool management</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -6630,10 +6622,11 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>MemoryPrivatePoolSize</key> <!-- deprecated (see MAINT-8091) -->
+ <key>MemoryPrivatePoolSize</key>
+ <!-- deprecated (see MAINT-8091) -->
<map>
<key>Comment</key>
- <string>DEPRECATED: Size of the private memory pool in MB (min. value is 256)</string>
+ <string>(Deprecated) Size of the private memory pool in MB (min. value is 256)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8326,7 +8319,7 @@
<key>QAModeEventHostPort</key>
<map>
<key>Comment</key>
- <string>DEPRECATED: Port on which lleventhost should listen</string>
+ <string>(Deprecated) Port on which lleventhost should listen</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
@@ -14060,10 +14053,11 @@
<key>Value</key>
<string>Default</string>
</map>
- <key>UseExternalBrowser</key> <!-- deprecated (see MAINT-4127) -->
+ <key>UseExternalBrowser</key>
+ <!-- deprecated (see MAINT-4127) -->
<map>
<key>Comment</key>
- <string>Use default browser when opening web pages instead of in-world browser.</string>
+ <string>(Deprecated) Use default browser when opening web pages instead of in-world browser.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -14335,19 +14329,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <!-- SL-12594 removes fixed function rendering
- <key>VertexShaderEnable</key>
- <map>
- <key>Comment</key>
- <string>Enable/disable all GLSL shaders (debug)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <-->
<key>VivoxAutoPostCrashDumps</key>
<map>
<key>Comment</key>
@@ -14436,7 +14417,7 @@
<key>Value</key>
<integer>44125</integer>
</map>
-
+
<key>VivoxVadAuto</key>
<map>
<key>Comment</key>
@@ -14473,8 +14454,7 @@
<key>VivoxVadSensitivity</key>
<map>
<key>Comment</key>
- <string>
- A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
+ <string>A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -14483,6 +14463,7 @@
<integer>0</integer>
</map>
<key>VoiceCallsFriendsOnly</key>
+ <!-- deprecated (see SL-12871) -->
<map>
<key>Comment</key>
<string>(Deprecated) Only accept voice calls from residents on your friends list</string>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index e6ee458719..f1bf8d76c2 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -56,7 +56,6 @@ RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
@@ -95,7 +94,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -127,7 +125,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -158,7 +155,6 @@ RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -189,7 +185,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -220,7 +215,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
@@ -251,7 +245,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -282,7 +275,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -312,7 +304,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
@@ -380,7 +371,6 @@ list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
@@ -394,7 +384,6 @@ list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index bc836a99ca..5542eee6ca 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -56,7 +56,6 @@ RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
@@ -94,7 +93,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -126,7 +124,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -157,7 +154,6 @@ RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -188,7 +184,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -219,7 +214,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderUseAdvancedAtmospherics 1 0
@@ -250,7 +244,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -281,7 +274,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -311,7 +303,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
@@ -379,7 +370,6 @@ list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
@@ -393,7 +383,6 @@ list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 68202a571f..bac6fd5708 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -56,7 +56,6 @@ RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
@@ -95,7 +94,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 0.5
-VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -127,7 +125,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 0.5
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -158,7 +155,6 @@ RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -189,7 +185,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -220,7 +215,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
@@ -251,7 +245,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -282,7 +275,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -312,7 +304,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
@@ -374,7 +365,6 @@ list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
@@ -388,7 +378,6 @@ list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3c50493d79..389448654a 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -108,7 +108,8 @@ const U8 AGENT_STATE_EDITING = 0x10;
// Autopilot constants
const F32 AUTOPILOT_HEIGHT_ADJUST_DISTANCE = 8.f; // meters
const F32 AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND = 1.f; // meters
-const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f; // seconds
+const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS_WALK = 1.5f; // seconds
+const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS_FLY = 2.5f; // seconds. Flying is less presize, needs a bit more time
const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;
const F64 CHAT_AGE_FAST_RATE = 3.0;
@@ -879,13 +880,12 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
}
// static
-void LLAgent::capabilityReceivedCallback(const LLUUID &region_id)
+void LLAgent::capabilityReceivedCallback(const LLUUID &region_id, LLViewerRegion *regionp)
{
- LLViewerRegion* region = gAgent.getRegion();
- if (region && region->getRegionID() == region_id)
+ if (regionp && regionp->getRegionID() == region_id)
{
- region->requestSimulatorFeatures();
- LLAppViewer::instance()->updateNameLookupUrl();
+ regionp->requestSimulatorFeatures();
+ LLAppViewer::instance()->updateNameLookupUrl(regionp);
}
}
@@ -936,7 +936,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (regionp->capabilitiesReceived())
{
regionp->requestSimulatorFeatures();
- LLAppViewer::instance()->updateNameLookupUrl();
+ LLAppViewer::instance()->updateNameLookupUrl(regionp);
}
else
{
@@ -962,11 +962,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (regionp->capabilitiesReceived())
{
- LLAppViewer::instance()->updateNameLookupUrl();
+ LLAppViewer::instance()->updateNameLookupUrl(regionp);
}
else
{
- regionp->setCapabilitiesReceivedCallback([](const LLUUID &region_id) {LLAppViewer::instance()->updateNameLookupUrl(); });
+ regionp->setCapabilitiesReceivedCallback([](const LLUUID &region_id, LLViewerRegion* regionp) {LLAppViewer::instance()->updateNameLookupUrl(regionp); });
}
}
@@ -1563,6 +1563,12 @@ void LLAgent::startAutoPilotGlobal(
{
return;
}
+
+ if (target_global.isExactlyZero())
+ {
+ LL_WARNS() << "Canceling attempt to start autopilot towards invalid position" << LL_ENDL;
+ return;
+ }
// Are there any pending callbacks from previous auto pilot requests?
if (mAutoPilotFinishedCallback)
@@ -1778,7 +1784,16 @@ void LLAgent::autoPilot(F32 *delta_yaw)
if (target_dist >= mAutoPilotTargetDist)
{
mAutoPilotNoProgressFrameCount++;
- if (mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS * gFPSClamped)
+ bool out_of_time = false;
+ if (getFlying())
+ {
+ out_of_time = mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS_FLY * gFPSClamped;
+ }
+ else
+ {
+ out_of_time = mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS_WALK * gFPSClamped;
+ }
+ if (out_of_time)
{
stopAutoPilot();
return;
@@ -1827,7 +1842,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)
F32 slow_distance;
if (getFlying())
{
- slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
+ slow_distance = llmax(8.f, mAutoPilotStopDistance + 5.f);
}
else
{
@@ -1871,14 +1886,41 @@ void LLAgent::autoPilot(F32 *delta_yaw)
}
else if (mAutoPilotTargetDist > mAutoPilotStopDistance)
{
- // walking/flying slow
+ // walking/flying slow
+ U32 movement_flag = 0;
+
if (at * direction > 0.9f)
{
- setControlFlags(AGENT_CONTROL_AT_POS);
- }
- else if (at * direction < -0.9f)
- {
- setControlFlags(AGENT_CONTROL_AT_NEG);
+ movement_flag = AGENT_CONTROL_AT_POS;
+ }
+ else if (at * direction < -0.9f)
+ {
+ movement_flag = AGENT_CONTROL_AT_NEG;
+ }
+
+ if (getFlying())
+ {
+ // flying is too fast and has high inertia, artificially slow it down
+ // Don't update flags too often, server might not react
+ static U64 last_time_microsec = 0;
+ U64 time_microsec = LLTimer::getTotalTime();
+ U64 delta = time_microsec - last_time_microsec;
+ // fly during ~0-40 ms, stop during ~40-250 ms
+ if (delta > 250000) // 250ms
+ {
+ // reset even if !movement_flag
+ last_time_microsec = time_microsec;
+ }
+ else if (delta > 40000) // 40 ms
+ {
+ clearControlFlags(AGENT_CONTROL_AT_POS | AGENT_CONTROL_AT_POS);
+ movement_flag = 0;
+ }
+ }
+
+ if (movement_flag)
+ {
+ setControlFlags(movement_flag);
}
}
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index a792d3e11f..134540c6b3 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -254,7 +254,7 @@ public:
boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t);
private:
- static void capabilityReceivedCallback(const LLUUID &region_id);
+ static void capabilityReceivedCallback(const LLUUID &region_id, LLViewerRegion *regionp);
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
parcel_changed_signal_t mParcelChangedSignal;
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index 134a34137b..ef56478106 100644
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -116,6 +116,7 @@ static const struct
};
static void setting_changed();
+static void ssl_verification_changed();
LLAppCoreHttp::HttpClass::HttpClass()
@@ -195,6 +196,23 @@ void LLAppCoreHttp::init()
LL_WARNS("Init") << "Failed to set SSL Verification. Reason: " << status.toString() << LL_ENDL;
}
+ // Set up Default SSL Verification option.
+ const std::string no_verify_ssl("NoVerifySSLCert");
+ if (gSavedSettings.controlExists(no_verify_ssl))
+ {
+ LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(no_verify_ssl);
+ if (cntrl_ptr.isNull())
+ {
+ LL_WARNS("Init") << "Unable to set signal on global setting '" << no_verify_ssl
+ << "'" << LL_ENDL;
+ }
+ else
+ {
+ mSSLNoVerifySignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&ssl_verification_changed));
+ LLCore::HttpOptions::setDefaultSSLVerifyPeer(!cntrl_ptr->getValue().asBoolean());
+ }
+ }
+
// Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy):
// 0 - None
// 1 - Basic start, stop simple transitions
@@ -253,20 +271,13 @@ void LLAppCoreHttp::init()
<< LL_ENDL;
}
- // Signal for global pipelining preference from settings
+ // Global pipelining setting
static const std::string http_pipelining("HttpPipelining");
if (gSavedSettings.controlExists(http_pipelining))
{
- LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(http_pipelining);
- if (cntrl_ptr.isNull())
- {
- LL_WARNS("Init") << "Unable to set signal on global setting '" << http_pipelining
- << "'" << LL_ENDL;
- }
- else
- {
- mPipelinedSignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&setting_changed));
- }
+ // Default to true (in ctor) if absent.
+ mPipelined = gSavedSettings.getBOOL(http_pipelining);
+ LL_INFOS("Init") << "HTTP Pipelining " << (mPipelined ? "enabled" : "disabled") << "!" << LL_ENDL;
}
// Register signals for settings and state changes
@@ -296,6 +307,11 @@ void setting_changed()
LLAppViewer::instance()->getAppCoreHttp().refreshSettings(false);
}
+void ssl_verification_changed()
+{
+ LLCore::HttpOptions::setDefaultSSLVerifyPeer(!gSavedSettings.getBOOL("NoVerifySSLCert"));
+}
+
namespace
{
// The NoOpDeletor is used when wrapping LLAppCoreHttp in a smart pointer below for
@@ -355,6 +371,7 @@ void LLAppCoreHttp::cleanup()
{
mHttpClasses[i].mSettingsSignal.disconnect();
}
+ mSSLNoVerifySignal.disconnect();
mPipelinedSignal.disconnect();
delete mRequest;
@@ -374,21 +391,6 @@ void LLAppCoreHttp::refreshSettings(bool initial)
{
LLCore::HttpStatus status;
- // Global pipelining setting
- bool pipeline_changed(false);
- static const std::string http_pipelining("HttpPipelining");
- if (gSavedSettings.controlExists(http_pipelining))
- {
- // Default to true (in ctor) if absent.
- bool pipelined(gSavedSettings.getBOOL(http_pipelining));
- if (pipelined != mPipelined)
- {
- mPipelined = pipelined;
- pipeline_changed = true;
- }
- LL_INFOS("Init") << "HTTP Pipelining " << (mPipelined ? "enabled" : "disabled") << "!" << LL_ENDL;
- }
-
for (int i(0); i < LL_ARRAY_SIZE(init_data); ++i)
{
const EAppPolicy app_policy(static_cast<EAppPolicy>(i));
@@ -417,7 +419,7 @@ void LLAppCoreHttp::refreshSettings(bool initial)
// Init- or run-time settings. Must use the queued request API.
// Pipelining changes
- if (initial || pipeline_changed)
+ if (initial)
{
const bool to_pipeline(mPipelined && init_data[i].mPipelined);
if (to_pipeline != mHttpClasses[app_policy].mPipelined)
@@ -460,7 +462,7 @@ void LLAppCoreHttp::refreshSettings(bool initial)
}
}
- if (initial || setting != mHttpClasses[app_policy].mConnLimit || pipeline_changed)
+ if (initial || setting != mHttpClasses[app_policy].mConnLimit)
{
// Set it and report. Strategies depend on pipelining:
//
diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h
index 95c138d598..751c498ab0 100644
--- a/indra/newview/llappcorehttp.h
+++ b/indra/newview/llappcorehttp.h
@@ -256,6 +256,7 @@ private:
HttpClass mHttpClasses[AP_COUNT];
bool mPipelined; // Global setting
boost::signals2::connection mPipelinedSignal; // Signal for 'HttpPipelining' setting
+ boost::signals2::connection mSSLNoVerifySignal; // Signal for 'NoVerifySSLCert' setting
static LLCore::HttpStatus sslVerify(const std::string &uri, const LLCore::HttpHandler::ptr_t &handler, void *appdata);
};
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 3f1b5139c5..aeb3294f53 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -66,6 +66,7 @@
constructViewer();
#if defined(LL_BUGSPLAT)
+ infos("bugsplat setup");
// Engage BugsplatStartupManager *before* calling initViewer() to handle
// any crashes during initialization.
// https://www.bugsplat.com/docs/platforms/os-x#initialization
@@ -74,6 +75,7 @@
[BugsplatStartupManager sharedManager].delegate = self;
[[BugsplatStartupManager sharedManager] start];
#endif
+ infos("post-bugsplat setup");
frameTimer = nil;
@@ -301,9 +303,13 @@ struct AttachmentInfo
// We "happen to know" that info[0].basename is "SecondLife.old" -- due to
// the fact that BugsplatMac only notices a crash during the viewer run
- // following the crash. Replace .old with .log to reduce confusion.
+ // following the crash.
+ // The Bugsplat service doesn't respect the MIME type above when returning
+ // the log data to a browser, so take this opportunity to rename the file
+ // from <base>.old to <base>_log.txt
info[0].basename =
- boost::filesystem::path(info[0].pathname).stem().string() + ".log";
+ boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt";
+ infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename);
NSMutableArray *attachments = [[NSMutableArray alloc] init];
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index e8a3305645..31d5a97ce6 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2347,6 +2347,52 @@ void LLAppearanceMgr::enforceCOFItemRestrictions(LLPointer<LLInventoryCallback>
}
}
+bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2)
+{
+ if (!item1 || !item2)
+ {
+ LL_WARNS() << "item1, item2 cannot be null, something is very wrong" << LL_ENDL;
+ return true;
+ }
+
+ return item1->getLinkedUUID() < item2->getLinkedUUID();
+}
+
+void get_sorted_base_and_cof_items(LLInventoryModel::item_array_t& cof_item_array, LLInventoryModel::item_array_t& outfit_item_array)
+{
+ LLUUID base_outfit_id = LLAppearanceMgr::instance().getBaseOutfitUUID();
+
+ if (base_outfit_id.notNull())
+ {
+ LLIsValidItemLink collector;
+ LLInventoryModel::cat_array_t sub_cat_array;
+
+ gInventory.collectDescendents(base_outfit_id,
+ sub_cat_array,
+ outfit_item_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+
+ LLInventoryModel::cat_array_t cof_cats;
+
+ gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), cof_cats, cof_item_array,
+ LLInventoryModel::EXCLUDE_TRASH, collector);
+
+ for (U32 i = 0; i < outfit_item_array.size(); ++i)
+ {
+ LLViewerInventoryItem* linked_item = outfit_item_array.at(i)->getLinkedItem();
+ if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+ {
+ outfit_item_array.erase(outfit_item_array.begin() + i);
+ break;
+ }
+ }
+
+ std::sort(cof_item_array.begin(), cof_item_array.end(), sort_by_linked_uuid);
+ std::sort(outfit_item_array.begin(), outfit_item_array.end(), sort_by_linked_uuid);
+ }
+}
+
+
void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
bool enforce_ordering,
nullary_func_t post_update_func)
@@ -2388,7 +2434,30 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
if (!validateClothingOrderingInfo())
{
- LL_WARNS() << "Clothing ordering error" << LL_ENDL;
+
+ LLInventoryModel::item_array_t outfit_item_array;
+ LLInventoryModel::item_array_t cof_item_array;
+ get_sorted_base_and_cof_items(cof_item_array, outfit_item_array);
+
+ if (outfit_item_array.size() == cof_item_array.size())
+ {
+ for (U32 i = 0; i < cof_item_array.size(); ++i)
+ {
+ LLViewerInventoryItem *cof_it = cof_item_array.at(i);
+ LLViewerInventoryItem *base_it = outfit_item_array.at(i);
+
+ if (cof_it->getActualDescription() != base_it->getActualDescription())
+ {
+ if (cof_it->getLinkedUUID() == base_it->getLinkedUUID())
+ {
+ cof_it->setDescription(base_it->getActualDescription());
+ gInventory.updateItem(cof_it);
+ }
+ }
+ }
+ LLAppearanceMgr::getInstance()->updateIsDirty();
+ }
+
}
BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF);
@@ -3017,17 +3086,6 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, LLPointer
}
}
-bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2)
-{
- if (!item1 || !item2)
- {
- LL_WARNS() << "item1, item2 cannot be null, something is very wrong" << LL_ENDL;
- return true;
- }
-
- return item1->getLinkedUUID() < item2->getLinkedUUID();
-}
-
void LLAppearanceMgr::updateIsDirty()
{
LLUUID cof = getCOF();
@@ -3626,7 +3684,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
}
llcoro::suspend();
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
return;
}
@@ -3693,7 +3751,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
return;
}
@@ -3733,7 +3791,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
LL_WARNS("Avatar") << "Bake retry #" << retryCount << " in " << timeout << " seconds." << LL_ENDL;
llcoro::suspendUntilTimeout(timeout);
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
return;
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c0971ba943..ddb4258030 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -730,14 +730,14 @@ LLAppViewer::LLAppViewer()
// from the previous viewer run between this constructor call and the
// init() call, which will overwrite the static_debug_info.log file for
// THIS run. So setDebugFileNames() early.
-#if LL_BUGSPLAT
+# ifdef LL_BUGSPLAT
// MAINT-8917: don't create a dump directory just for the
// static_debug_info.log file
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
-#else // ! LL_BUGSPLAT
+# else // ! LL_BUGSPLAT
// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
-#endif // ! LL_BUGSPLAT
+# endif // ! LL_BUGSPLAT
mDumpPath = logdir;
setMiniDumpDir(logdir);
setDebugFileNames(logdir);
@@ -762,17 +762,6 @@ public:
}
};
-namespace {
-// With Xcode 6, _exit() is too magical to use with boost::bind(), so provide
-// this little helper function.
-void fast_exit(int rc)
-{
- _exit(rc);
-}
-
-
-}
-
bool LLAppViewer::init()
{
@@ -824,9 +813,9 @@ bool LLAppViewer::init()
if (rc >= 0)
{
// QAModeTermCode set, terminate with that rc on LL_ERRS. Use
- // fast_exit() rather than exit() because normal cleanup depends too
+ // _exit() rather than exit() because normal cleanup depends too
// much on successful startup!
- LLError::setFatalFunction(boost::bind(fast_exit, rc));
+ LLError::setFatalFunction([rc](const std::string&){ _exit(rc); });
}
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
@@ -1120,19 +1109,27 @@ bool LLAppViewer::init()
if (count > 0 && v1 <= 10)
{
LL_INFOS("AppInit") << "Detected obsolete intel driver: " << driver << LL_ENDL;
- LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedIntelDriver");
- std::string gpu_name = ll_safe_string((const char *)glGetString(GL_RENDERER));
- details.setArg("[VERSION]", driver);
- details.setArg("[GPUNAME]", gpu_name);
- S32 button = OSMessageBox(details.getString(),
- LLStringUtil::null,
- OSMB_YESNO);
- if (OSBTN_YES == button && gViewerWindow)
+
+ if (!gViewerWindow->getInitAlert().empty() // graphic initialization crashed on last run
+ || LLVersionInfo::getInstance()->getChannelAndVersion() != gLastRunVersion // viewer was updated
+ || mNumSessions % 20 == 0 //periodically remind user to update driver
+ )
{
- std::string url = LLWeb::escapeURL(LLTrans::getString("IntelDriverPage"));
- if (gViewerWindow->getWindow())
+ LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedIntelDriver");
+ std::string gpu_name = ll_safe_string((const char *)glGetString(GL_RENDERER));
+ LL_INFOS("AppInit") << "Notifying user about obsolete intel driver for " << gpu_name << LL_ENDL;
+ details.setArg("[VERSION]", driver);
+ details.setArg("[GPUNAME]", gpu_name);
+ S32 button = OSMessageBox(details.getString(),
+ LLStringUtil::null,
+ OSMB_YESNO);
+ if (OSBTN_YES == button && gViewerWindow)
{
- gViewerWindow->getWindow()->spawnWebBrowser(url, false);
+ std::string url = LLWeb::escapeURL(LLTrans::getString("IntelDriverPage"));
+ if (gViewerWindow->getWindow())
+ {
+ gViewerWindow->getWindow()->spawnWebBrowser(url, false);
+ }
}
}
}
@@ -2196,28 +2193,6 @@ bool LLAppViewer::cleanup()
return true;
}
-// A callback for LL_ERRS() to call during the watchdog error.
-void watchdog_llerrs_callback(const std::string &error_string)
-{
- gLLErrorActivated = true;
-
- gDebugInfo["FatalMessage"] = error_string;
- LLAppViewer::instance()->writeDebugInfo();
-
-#ifdef LL_WINDOWS
- RaiseException(0,0,0,0);
-#else
- raise(SIGQUIT);
-#endif
-}
-
-// A callback for the watchdog to call.
-void watchdog_killer_callback()
-{
- LLError::setFatalFunction(watchdog_llerrs_callback);
- LL_ERRS() << "Watchdog killer event" << LL_ENDL;
-}
-
bool LLAppViewer::initThreads()
{
static const bool enable_threads = true;
@@ -2252,24 +2227,23 @@ bool LLAppViewer::initThreads()
return true;
}
-void errorCallback(const std::string &error_string)
+void errorCallback(LLError::ELevel level, const std::string &error_string)
{
+ if (level == LLError::LEVEL_ERROR)
+ {
#ifndef LL_RELEASE_FOR_DOWNLOAD
- OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK);
+ OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK);
#endif
- //Set the ErrorActivated global so we know to create a marker file
- gLLErrorActivated = true;
-
- gDebugInfo["FatalMessage"] = error_string;
- // We're not already crashing -- we simply *intend* to crash. Since we
- // haven't actually trashed anything yet, we can afford to write the whole
- // static info file.
- LLAppViewer::instance()->writeDebugInfo();
+ //Set the ErrorActivated global so we know to create a marker file
+ gLLErrorActivated = true;
-#ifndef SHADER_CRASH_NONFATAL
- LLError::crashAndLoop(error_string);
-#endif
+ gDebugInfo["FatalMessage"] = error_string;
+ // We're not already crashing -- we simply *intend* to crash. Since we
+ // haven't actually trashed anything yet, we can afford to write the whole
+ // static info file.
+ LLAppViewer::instance()->writeDebugInfo();
+ }
}
void LLAppViewer::initLoggingAndGetLastDuration()
@@ -2280,7 +2254,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "")
,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")
);
- LLError::setFatalFunction(errorCallback);
+ LLError::addGenericRecorder(&errorCallback);
//LLError::setTimeFunction(getRuntime);
// Remove the last ".old" log file.
@@ -3039,11 +3013,16 @@ bool LLAppViewer::initWindow()
use_watchdog = bool(watchdog_enabled_setting);
}
+ LL_INFOS("AppInit") << "watchdog"
+ << (use_watchdog ? " " : " NOT ")
+ << "enabled"
+ << " (setting = " << watchdog_enabled_setting << ")"
+ << LL_ENDL;
+
if (use_watchdog)
{
- LLWatchdog::getInstance()->init(watchdog_killer_callback);
+ LLWatchdog::getInstance()->init();
}
- LL_INFOS("AppInit") << "watchdog setting is done." << LL_ENDL;
LLNotificationsUI::LLNotificationManager::getInstance();
@@ -3125,6 +3104,15 @@ bool LLAppViewer::initWindow()
void LLAppViewer::writeDebugInfo(bool isStatic)
{
+#if LL_WINDOWS && LL_BUGSPLAT
+ // bugsplat does not create dump folder and debug logs are written directly
+ // to logs folder, so it conflicts with main instance
+ if (mSecondInstance)
+ {
+ return;
+ }
+#endif
+
//Try to do the minimum when writing data during a crash.
std::string* debug_filename;
debug_filename = ( isStatic
@@ -3453,7 +3441,7 @@ void LLAppViewer::writeSystemInfo()
if (! gDebugInfo.has("Dynamic") )
gDebugInfo["Dynamic"] = LLSD::emptyMap();
-#if LL_WINDOWS
+#if LL_WINDOWS && !LL_BUGSPLAT
gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
#else
//Not ideal but sufficient for good reporting.
@@ -3476,8 +3464,8 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
- gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB().value());
- gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());
+ gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value());
+ gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());
gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple();
// The user is not logged on yet, but record the current grid choice login url
@@ -3490,12 +3478,18 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["MainloopThreadID"] = (S32)thread_id;
#endif
+#ifndef LL_BUGSPLAT
// "CrashNotHandled" is set here, while things are running well,
// in case of a freeze. If there is a freeze, the crash logger will be launched
// and can read this value from the debug_info.log.
// If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze,
// then the value of "CrashNotHandled" will be set to true.
- gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true;
+ gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true);
+#else // LL_BUGSPLAT
+ // "CrashNotHandled" is obsolete; it used (not very successsfully)
+ // to try to distinguish crashes from freezes - the intent here to to avoid calling it a freeze
+ gDebugInfo["CrashNotHandled"] = LLSD::Boolean(false);
+#endif // ! LL_BUGSPLAT
// Insert crash host url (url to post crash log to) if configured. This insures
// that the crash report will go to the proper location in the case of a
@@ -3526,7 +3520,7 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
- gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
+ gDebugInfo["FirstLogin"] = LLSD::Boolean(gAgent.isFirstLogin());
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
@@ -3656,7 +3650,7 @@ void LLAppViewer::handleViewerCrash()
// The crash is being handled here so set this value to false.
// Otherwise the crash logger will think this crash was a freeze.
- gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false;
+ gDebugInfo["Dynamic"]["CrashNotHandled"] = LLSD::Boolean(false);
//Write out the crash status file
//Use marker file style setup, as that's the simplest, especially since
@@ -3729,6 +3723,8 @@ void LLAppViewer::handleViewerCrash()
if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]);
+ gDebugInfo["FatalMessage"] = LLError::getFatalMessage();
+
// Close the debug file
pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead.
}
@@ -3827,9 +3823,8 @@ void LLAppViewer::processMarkerFiles()
else if (marker_is_same_version)
{
// the file existed, is ours, and matched our version, so we can report on what it says
- LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL;
- gLastExecEvent = LAST_EXEC_FROZE;
-
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL;
+ gLastExecEvent = LAST_EXEC_OTHER_CRASH;
}
else
{
@@ -3961,10 +3956,13 @@ void LLAppViewer::removeMarkerFiles()
void LLAppViewer::removeDumpDir()
{
- //Call this routine only on clean exit. Crash reporter will clean up
- //its locking table for us.
- std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
- gDirUtilp->deleteDirAndContents(dump_dir);
+ if (gDirUtilp->dumpDirExists())
+ {
+ //Call this routine only on clean exit. Crash reporter will clean up
+ //its locking table for us.
+ std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ gDirUtilp->deleteDirAndContents(dump_dir);
+ }
}
void LLAppViewer::forceQuit()
@@ -5373,10 +5371,9 @@ void LLAppViewer::sendLogoutRequest()
}
}
-void LLAppViewer::updateNameLookupUrl()
+void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp)
{
- LLViewerRegion* region = gAgent.getRegion();
- if (!region || !region->capabilitiesReceived())
+ if (!regionp || !regionp->capabilitiesReceived())
{
return;
}
@@ -5385,7 +5382,7 @@ void LLAppViewer::updateNameLookupUrl()
bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
std::string name_lookup_url;
name_lookup_url.reserve(128); // avoid a memory allocation below
- name_lookup_url = region->getCapability("GetDisplayNames");
+ name_lookup_url = regionp->getCapability("GetDisplayNames");
bool have_capability = !name_lookup_url.empty();
if (have_capability)
{
@@ -5696,6 +5693,33 @@ void LLAppViewer::forceErrorDriverCrash()
glDeleteTextures(1, NULL);
}
+void LLAppViewer::forceErrorCoroutineCrash()
+{
+ LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL;
+ LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); });
+}
+
+void LLAppViewer::forceErrorThreadCrash()
+{
+ class LLCrashTestThread : public LLThread
+ {
+ public:
+
+ LLCrashTestThread() : LLThread("Crash logging test thread")
+ {
+ }
+
+ void run()
+ {
+ LL_ERRS() << "This is a deliberate llerror in thread" << LL_ENDL;
+ }
+ };
+
+ LL_WARNS() << "This is a deliberate crash in a thread" << LL_ENDL;
+ LLCrashTestThread *thread = new LLCrashTestThread();
+ thread->start();
+}
+
void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs)
{
if(!mMainloopTimeout)
@@ -5739,11 +5763,6 @@ void LLAppViewer::pauseMainloopTimeout()
void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
{
-// if(!restoreErrorTrap())
-// {
-// LL_WARNS() << "!!!!!!!!!!!!! Its an error trap!!!!" << state << LL_ENDL;
-// }
-
if(mMainloopTimeout)
{
if(secs < 0.0f)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 5ceb540784..0afb70958c 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -57,6 +57,7 @@ class LLImageDecodeThread;
class LLTextureFetch;
class LLWatchdogTimeout;
class LLViewerJoystick;
+class LLViewerRegion;
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
@@ -150,6 +151,8 @@ public:
virtual void forceErrorInfiniteLoop();
virtual void forceErrorSoftwareException();
virtual void forceErrorDriverCrash();
+ virtual void forceErrorCoroutineCrash();
+ virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
@@ -209,7 +212,7 @@ public:
// llcorehttp init/shutdown/config information.
LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
- void updateNameLookupUrl();
+ void updateNameLookupUrl(const LLViewerRegion* regionp);
protected:
virtual bool initWindow(); // Initialize the viewer's window.
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 662164af2d..42946e4415 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -68,39 +68,21 @@ namespace
int gArgC;
char** gArgV;
LLAppViewerMacOSX* gViewerAppPtr = NULL;
-
- void (*gOldTerminateHandler)() = NULL;
std::string gHandleSLURL;
}
-static void exceptionTerminateHandler()
-{
- // reinstall default terminate() handler in case we re-terminate.
- if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler);
- // treat this like a regular viewer crash, with nice stacktrace etc.
- long *null_ptr;
- null_ptr = 0;
- *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad.
- //LLAppViewer::handleViewerCrash();
- // we've probably been killed-off before now, but...
- gOldTerminateHandler(); // call old terminate() handler
-}
-
void constructViewer()
{
// Set the working dir to <bundle>/Contents/Resources
if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
{
- LL_WARNS() << "Could not change directory to "
+ LL_WARNS("InitOSX") << "Could not change directory to "
<< gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
<< LL_ENDL;
}
gViewerAppPtr = new LLAppViewerMacOSX();
- // install unexpected exception handler
- gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
-
gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
}
@@ -109,7 +91,7 @@ bool initViewer()
bool ok = gViewerAppPtr->init();
if(!ok)
{
- LL_WARNS() << "Application init failed." << LL_ENDL;
+ LL_WARNS("InitOSX") << "Application init failed." << LL_ENDL;
}
else if (!gHandleSLURL.empty())
{
@@ -172,7 +154,7 @@ class CrashMetadataSingleton: public CrashMetadata, public LLSingleton<CrashMeta
std::string get_metadata(const LLSD& info, const LLSD::String& key) const
{
std::string data(info[key].asString());
- LL_INFOS() << " " << key << "='" << data << "'" << LL_ENDL;
+ LL_INFOS("Bugsplat") << " " << key << "='" << data << "'" << LL_ENDL;
return data;
}
};
@@ -188,22 +170,22 @@ CrashMetadataSingleton::CrashMetadataSingleton()
LLSD info;
if (! static_file.is_open())
{
- LL_INFOS() << "Can't open '" << staticDebugPathname
+ LL_WARNS("Bugsplat") << "Can't open '" << staticDebugPathname
<< "'; no metadata about previous run" << LL_ENDL;
}
else if (! LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED))
{
- LL_INFOS() << "Can't parse '" << staticDebugPathname
+ LL_WARNS("Bugsplat") << "Can't parse '" << staticDebugPathname
<< "'; no metadata about previous run" << LL_ENDL;
}
else
{
- LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL;
- logFilePathname = get_metadata(info, "SLLog");
- userSettingsPathname = get_metadata(info, "SettingsFilename");
+ LL_INFOS("Bugsplat") << "Previous run metadata from '" << staticDebugPathname << "':" << LL_ENDL;
+ logFilePathname = get_metadata(info, "SLLog");
+ userSettingsPathname = get_metadata(info, "SettingsFilename");
accountSettingsPathname = get_metadata(info, "PerAccountSettingsFilename");
- OSInfo = get_metadata(info, "OSInfo");
- agentFullname = get_metadata(info, "LoginName");
+ OSInfo = get_metadata(info, "OSInfo");
+ agentFullname = get_metadata(info, "LoginName");
// Translate underscores back to spaces
LLStringUtil::replaceChar(agentFullname, '_', ' ');
regionName = get_metadata(info, "CurrentRegion");
@@ -219,7 +201,7 @@ CrashMetadata& CrashMetadata_instance()
void infos(const std::string& message)
{
- LL_INFOS() << message << LL_ENDL;
+ LL_INFOS("InitOSX", "Bugsplat") << message << LL_ENDL;
}
int main( int argc, char **argv )
@@ -242,14 +224,11 @@ bool LLAppViewerMacOSX::init()
{
bool success = LLAppViewer::init();
-#if LL_SEND_CRASH_REPORTS
if (success)
{
LLAppViewer* pApp = LLAppViewer::instance();
pApp->initCrashReporting();
}
-#endif
-
return success;
}
@@ -334,11 +313,12 @@ bool LLAppViewerMacOSX::restoreErrorTrap()
unsigned int reset_count = 0;
-#define SET_SIG(S) sigaction(SIGABRT, &act, &old_act); \
- if(act.sa_sigaction != old_act.sa_sigaction) \
- ++reset_count;
+#define SET_SIG(SIGNAL) sigaction(SIGNAL, &act, &old_act); \
+ if(act.sa_sigaction != old_act.sa_sigaction) ++reset_count;
// Synchronous signals
- SET_SIG(SIGABRT)
+# ifndef LL_BUGSPLAT
+ SET_SIG(SIGABRT) // let bugsplat catch this
+# endif
SET_SIG(SIGALRM)
SET_SIG(SIGBUS)
SET_SIG(SIGFPE)
@@ -369,6 +349,10 @@ bool LLAppViewerMacOSX::restoreErrorTrap()
void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze)
{
+#if defined LL_BUGSPLAT
+ LL_DEBUGS("InitOSX", "Bugsplat") << "using BugSplat crash logger" << LL_ENDL;
+#elif LL_SEND_CRASH_REPORTS
+ LL_DEBUGS("InitOSX") << "Initializing legacy crash logger" << LL_ENDL;
std::string command_str = "mac-crash-logger.app";
std::stringstream pid_str;
@@ -380,6 +364,9 @@ void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze)
LL_WARNS() << "about to launch mac-crash-logger" << pid_str.str()
<< " " << logdir << " " << appname << LL_ENDL;
launchApplication(&command_str, &args);
+#else
+ LL_DEBUGS("InitOSX") << "No crash logger enabled" << LL_ENDL;
+#endif // ! LL_BUGSPLAT
}
std::string LLAppViewerMacOSX::generateSerialNumber()
@@ -391,7 +378,8 @@ std::string LLAppViewerMacOSX::generateSerialNumber()
CFStringRef serialNumber = NULL;
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("IOPlatformExpertDevice"));
- if (platformExpert) {
+ if (platformExpert)
+ {
serialNumber = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert,
CFSTR(kIOPlatformSerialNumberKey),
kCFAllocatorDefault, 0);
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 9b1c0d1f8b..1896248502 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -118,16 +118,20 @@ namespace
{
if (nCode == MDSCB_EXCEPTIONCODE)
{
- // send the main viewer log file
- // widen to wstring, convert to __wchar_t, then pass c_str()
- sBugSplatSender->sendAdditionalFile(
- WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
+ // second instance does not have own log files
+ if (!LLAppViewer::instance()->isSecondInstance())
+ {
+ // send the main viewer log file
+ // widen to wstring, convert to __wchar_t, then pass c_str()
+ sBugSplatSender->sendAdditionalFile(
+ WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
- sBugSplatSender->sendAdditionalFile(
- WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
+ sBugSplatSender->sendAdditionalFile(
+ WCSTR(*LLAppViewer::instance()->getStaticDebugFile()));
+ }
sBugSplatSender->sendAdditionalFile(
- WCSTR(*LLAppViewer::instance()->getStaticDebugFile()));
+ WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
// We don't have an email address for any user. Hijack this
// metadata field for the platform identifier.
@@ -177,7 +181,7 @@ static void exceptionTerminateHandler()
long *null_ptr;
null_ptr = 0;
*null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad.
- //LLAppViewer::handleViewerCrash();
+
// we've probably been killed-off before now, but...
gOldTerminateHandler(); // call old terminate() handler
}
@@ -365,10 +369,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
-#if LL_SEND_CRASH_REPORTS
- // ::SetUnhandledExceptionFilter(catchallCrashHandler);
-#endif
-
// Set a debug info flag to indicate if multiple instances are running.
bool found_other_instance = !create_app_mutex();
gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance);
@@ -609,6 +609,13 @@ bool LLAppViewerWin32::init()
#else // LL_BUGSPLAT
#pragma message("Building with BugSplat")
+ if (!isSecondInstance())
+ {
+ // Cleanup previous session
+ std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
+ LLFile::remove(log_file, ENOENT);
+ }
+
std::string build_data_fname(
gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
// Use llifstream instead of std::ifstream because LL_PATH_EXECUTABLE
@@ -616,7 +623,7 @@ bool LLAppViewerWin32::init()
llifstream inf(build_data_fname.c_str());
if (! inf.is_open())
{
- LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
+ LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname
<< "'" << LL_ENDL;
}
else
@@ -626,7 +633,7 @@ bool LLAppViewerWin32::init()
if (! reader.parse(inf, build_data, false)) // don't collect comments
{
// gah, the typo is baked into Json::Reader API
- LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
+ LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname
<< "': " << reader.getFormatedErrorMessages() << LL_ENDL;
}
else
@@ -634,7 +641,7 @@ bool LLAppViewerWin32::init()
Json::Value BugSplat_DB = build_data["BugSplat DB"];
if (! BugSplat_DB)
{
- LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
+ LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
<< build_data_fname << "'" << LL_ENDL;
}
else
@@ -645,18 +652,35 @@ bool LLAppViewerWin32::init()
LL_VIEWER_VERSION_PATCH << '.' <<
LL_VIEWER_VERSION_BUILD));
+ DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
+ MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
+
+ bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT");
+ if (needs_log_file)
+ {
+ // Startup only!
+ LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
+ dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
+ }
+
// have to convert normal wide strings to strings of __wchar_t
sBugSplatSender = new MiniDmpSender(
WCSTR(BugSplat_DB.asString()),
WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
WCSTR(version_string),
nullptr, // szAppIdentifier -- set later
- MDSF_NONINTERACTIVE | // automatically submit report without prompting
- MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
+ dwFlags);
sBugSplatSender->setCallback(bugsplatSendLog);
+ if (needs_log_file)
+ {
+ // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
+ std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
+ sBugSplatSender->setLogFilePath(WCSTR(log_file));
+ }
+
// engage stringize() overload that converts from wstring
- LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
+ LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
<< ' ' << stringize(version_string) << ')' << LL_ENDL;
} // got BugSplat_DB
} // parsed build_data.json
@@ -685,6 +709,16 @@ bool LLAppViewerWin32::cleanup()
return result;
}
+void LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo)
+{
+#if defined(LL_BUGSPLAT)
+ if (sBugSplatSender)
+ {
+ sBugSplatSender->createReport((EXCEPTION_POINTERS*)pExcepInfo);
+ }
+#endif // LL_BUGSPLAT
+}
+
void LLAppViewerWin32::initLoggingAndGetLastDuration()
{
LLAppViewer::initLoggingAndGetLastDuration();
@@ -813,8 +847,7 @@ bool LLAppViewerWin32::beingDebugged()
bool LLAppViewerWin32::restoreErrorTrap()
{
- return true;
- //return LLWinDebug::checkExceptionHandler();
+ return true; // we don't check for handler collisions on windows, so just say they're ok
}
void LLAppViewerWin32::initCrashReporting(bool reportFreeze)
diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h
index c5fae6a3a3..83ae875a15 100644
--- a/indra/newview/llappviewerwin32.h
+++ b/indra/newview/llappviewerwin32.h
@@ -40,20 +40,22 @@ public:
//
// Main application logic
//
- virtual bool init(); // Override to do application initialization
- virtual bool cleanup();
+ bool init() override; // Override to do application initialization
+ bool cleanup() override;
+
+ void reportCrashToBugsplat(void* pExcepInfo) override;
protected:
- virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info.
- virtual void initConsole(); // Initialize OS level debugging console.
- virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.
- virtual bool initParseCommandLine(LLCommandLineParser& clp);
+ void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info.
+ void initConsole() override; // Initialize OS level debugging console.
+ bool initHardwareTest() override; // Win32 uses DX9 to test hardware.
+ bool initParseCommandLine(LLCommandLineParser& clp) override;
- virtual bool beingDebugged();
- virtual bool restoreErrorTrap();
- virtual void initCrashReporting(bool reportFreeze);
+ bool beingDebugged() override;
+ bool restoreErrorTrap() override;
+ void initCrashReporting(bool reportFreeze) override;
- virtual bool sendURLToOtherInstance(const std::string& url);
+ bool sendURLToOtherInstance(const std::string& url) override;
std::string generateSerialNumber();
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 3aaaaf52f5..bf10a9f2b4 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -347,7 +347,7 @@ void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID paren
bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater,
const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
{
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
// Reply from coroutine came on shutdown
// We are quiting, don't start any more coroutines!
diff --git a/indra/newview/lldelayedgestureerror.cpp b/indra/newview/lldelayedgestureerror.cpp
index ef1b644ad4..934a38bb8e 100644
--- a/indra/newview/lldelayedgestureerror.cpp
+++ b/indra/newview/lldelayedgestureerror.cpp
@@ -113,7 +113,7 @@ bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
}
}
- if(!LLApp::isQuitting())
+ if(!LLApp::isExiting())
{
LLNotificationsUtil::add(ent.mNotifyName, args);
}
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 190051d763..cc2b1cc42c 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -1029,7 +1029,7 @@ void LLEnvironment::onRegionChange()
}
if (!cur_region->capabilitiesReceived())
{
- cur_region->setCapabilitiesReceivedCallback([](const LLUUID &region_id) { LLEnvironment::instance().requestRegion(); });
+ cur_region->setCapabilitiesReceivedCallback([](const LLUUID &region_id, LLViewerRegion* regionp) { LLEnvironment::instance().requestRegion(); });
return;
}
requestRegion();
@@ -1154,9 +1154,38 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
}
else if (!environment->getSky())
{
- LL_DEBUGS("ENVIRONMENT") << "Blank sky for " << env_selection_to_string(env) << ". Reusing environment for sky." << LL_ENDL;
- environment->setSky(mCurrentEnvironment->getSky());
- environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ if (mCurrentEnvironment->getEnvironmentSelection() != ENV_NONE)
+ {
+ // Note: This looks suspicious. Shouldn't we assign whole day if mCurrentEnvironment has whole day?
+ // and then add water/sky on top
+ // This looks like it will result in sky using single keyframe instead of whole day if day is present
+ // when setting static water without static sky
+ environment->setSky(mCurrentEnvironment->getSky());
+ environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ }
+ else
+ {
+ // Environment is not properly initialized yet, but we should have environment by this point
+ DayInstance::ptr_t substitute = getEnvironmentInstance(ENV_PARCEL, true);
+ if (!substitute || !substitute->getSky())
+ {
+ substitute = getEnvironmentInstance(ENV_REGION, true);
+ }
+ if (!substitute || !substitute->getSky())
+ {
+ substitute = getEnvironmentInstance(ENV_DEFAULT, true);
+ }
+
+ if (substitute && substitute->getSky())
+ {
+ environment->setSky(substitute->getSky());
+ environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Failed to assign substitute water/sky, environment is not properly initialized" << LL_ENDL;
+ }
+ }
}
if (fixed.second)
@@ -1167,9 +1196,38 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
}
else if (!environment->getWater())
{
- LL_DEBUGS("ENVIRONMENT") << "Blank water for " << env_selection_to_string(env) << ". Reusing environment for water." << LL_ENDL;
- environment->setWater(mCurrentEnvironment->getWater());
- environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ if (mCurrentEnvironment->getEnvironmentSelection() != ENV_NONE)
+ {
+ // Note: This looks suspicious. Shouldn't we assign whole day if mCurrentEnvironment has whole day?
+ // and then add water/sky on top
+ // This looks like it will result in water using single keyframe instead of whole day if day is present
+ // when setting static sky without static water
+ environment->setWater(mCurrentEnvironment->getWater());
+ environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ }
+ else
+ {
+ // Environment is not properly initialized yet, but we should have environment by this point
+ DayInstance::ptr_t substitute = getEnvironmentInstance(ENV_PARCEL, true);
+ if (!substitute || !substitute->getWater())
+ {
+ substitute = getEnvironmentInstance(ENV_REGION, true);
+ }
+ if (!substitute || !substitute->getWater())
+ {
+ substitute = getEnvironmentInstance(ENV_DEFAULT, true);
+ }
+
+ if (substitute && substitute->getWater())
+ {
+ environment->setWater(substitute->getWater());
+ environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Failed to assign substitute water/sky, environment is not properly initialized" << LL_ENDL;
+ }
+ }
}
if (!mSignalEnvChanged.empty())
@@ -1694,8 +1752,11 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
}
else
{
- setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
mTrackAltitudes = envinfo->mAltitudes;
+ // update track selection based on new altitudes
+ mCurrentTrack = calculateSkyTrackForAltitude(gAgent.getPositionAgent().mV[VZ]);
+
+ setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
}
LL_DEBUGS("ENVIRONMENT") << "Altitudes set to {" << mTrackAltitudes[0] << ", "<< mTrackAltitudes[1] << ", " << mTrackAltitudes[2] << ", " << mTrackAltitudes[3] << LL_ENDL;
@@ -1927,6 +1988,10 @@ void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environ
{
LL_WARNS("ENVIRONMENT") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
}
+ else if (LLApp::isExiting())
+ {
+ return;
+ }
else
{
LLSD environment = result[KEY_ENVIRONMENT];
@@ -2014,7 +2079,19 @@ void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInf
LL_WARNS("ENVIRONMENT") << "Couldn't update Windlight settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
notify = LLSD::emptyMap();
- notify["FAIL_REASON"] = result["message"].asString();
+ std::string reason = result["message"].asString();
+ if (reason.empty())
+ {
+ notify["FAIL_REASON"] = status.toString();
+ }
+ else
+ {
+ notify["FAIL_REASON"] = reason;
+ }
+ }
+ else if (LLApp::isExiting())
+ {
+ return;
}
else
{
@@ -2076,7 +2153,19 @@ void LLEnvironment::coroResetEnvironment(S32 parcel_id, S32 track_no, environmen
LL_WARNS("ENVIRONMENT") << "Couldn't reset Windlight settings in " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
notify = LLSD::emptyMap();
- notify["FAIL_REASON"] = result["message"].asString();
+ std::string reason = result["message"].asString();
+ if (reason.empty())
+ {
+ notify["FAIL_REASON"] = status.toString();
+ }
+ else
+ {
+ notify["FAIL_REASON"] = reason;
+ }
+ }
+ else if (LLApp::isExiting())
+ {
+ return;
}
else
{
@@ -2315,6 +2404,15 @@ void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos)
return;
mCurrentTrack = trackno;
+
+ LLViewerRegion* cur_region = gAgent.getRegion();
+ if (!cur_region || !cur_region->capabilitiesReceived())
+ {
+ // Environment not ready, environment will be updated later, don't cause 'blend' yet.
+ // But keep mCurrentTrack updated in case we won't get new altitudes for some reason
+ return;
+ }
+
for (S32 env = ENV_LOCAL; env < ENV_DEFAULT; ++env)
{
if (mEnvironments[env])
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 171858e472..1fbd198019 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -236,6 +236,7 @@ void LLFloaterAbout::fetchServerReleaseNotesCoro(const std::string& cap_url)
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
+ httpOpts->setSSLVerifyPeer(false); // We want this data even if SSL verification fails
LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts);
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 0a0e5ffc06..464e7ff4a2 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -996,7 +996,8 @@ void LLFloaterBuyLandUI::draw()
// virtual
BOOL LLFloaterBuyLandUI::canClose()
{
- bool can_close = (mTransaction ? FALSE : TRUE) && mCurrency.canCancel();
+ // mTransactionType check for pre-buy estimation stage and mCurrency to allow exit after transaction
+ bool can_close = !mTransaction && (mTransactionType != TransactionBuy || mCurrency.canCancel());
if (!can_close)
{
// explain to user why they can't do this, see DEV-9605
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
index eb93a6a75a..6b1d9306fb 100644
--- a/indra/newview/llfloatercreatelandmark.cpp
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -320,4 +320,4 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
}
}
}
-} \ No newline at end of file
+}
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp
index e888144b6a..2850951668 100644
--- a/indra/newview/llfloatereditenvironmentbase.cpp
+++ b/indra/newview/llfloatereditenvironmentbase.cpp
@@ -262,7 +262,7 @@ void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, cons
{
const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
LLUUID parent_id = mInventoryItem->getParentUUID();
- if (marketplacelistings_id == parent_id)
+ if (marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(mInventoryItem->getUUID(), gInventory.getLibraryRootFolderID()))
{
parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
}
diff --git a/indra/newview/llfloaterexperienceprofile.cpp b/indra/newview/llfloaterexperienceprofile.cpp
index 2c9a8e64b7..a99a096ea7 100644
--- a/indra/newview/llfloaterexperienceprofile.cpp
+++ b/indra/newview/llfloaterexperienceprofile.cpp
@@ -211,6 +211,20 @@ bool LLFloaterExperienceProfile::experiencePermission( LLHandle<LLFloaterExperie
return false;
}
+bool LLFloaterExperienceProfile::matchesKey(const LLSD& key)
+{
+ if (key.has("experience_id"))
+ {
+ return mExperienceId == key["experience_id"].asUUID();
+ }
+ else if (key.isUUID())
+ {
+ return mExperienceId == key.asUUID();
+ }
+ // Assume NULL uuid
+ return mExperienceId.isNull();
+}
+
void LLFloaterExperienceProfile::onClickEdit()
{
diff --git a/indra/newview/llfloaterexperienceprofile.h b/indra/newview/llfloaterexperienceprofile.h
index 1394418d91..f9b6e2e2eb 100644
--- a/indra/newview/llfloaterexperienceprofile.h
+++ b/indra/newview/llfloaterexperienceprofile.h
@@ -51,6 +51,8 @@ public:
LLFloaterExperienceProfile(const LLSD& data);
virtual ~LLFloaterExperienceProfile();
+
+ /* virtual */ bool matchesKey(const LLSD& key);
LLUUID getExperienceId() const { return mExperienceId; }
void setPreferences( const LLSD& content );
diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp
index faa7e9f3db..9745e17bbb 100644
--- a/indra/newview/llfloatergridstatus.cpp
+++ b/indra/newview/llfloatergridstatus.cpp
@@ -95,6 +95,7 @@ void LLFloaterGridStatus::getGridStatusRSSCoro()
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ httpOpts->setSSLVerifyPeer(false); // We want this data even if SSL fails
httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
std::string url = gSavedSettings.getString("GridStatusRSS");
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index f2efef0c33..63bce3d2eb 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -122,8 +122,7 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_
}
}
- // Decrement the cursor
- getWindow()->decBusyCount();
+
getChildView("loading_label")->setVisible( false);
closeFloater();
}
@@ -302,3 +301,9 @@ bool LLFloaterURLEntry::callback_clear_url_list(const LLSD& notification, const
}
return false;
}
+
+void LLFloaterURLEntry::onClose( bool app_quitting )
+{
+ // Decrement the cursor
+ getWindow()->decBusyCount();
+}
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index 20f4604907..04a8eca069 100644
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -42,6 +42,7 @@ public:
// that panel via the handle.
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle, const std::string media_url);
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onClose( bool app_quitting );
void headerFetchComplete(S32 status, const std::string& mime_type);
bool addURLToCombobox(const std::string& media_url);
diff --git a/indra/newview/llfloaterwindowsize.cpp b/indra/newview/llfloaterwindowsize.cpp
index ec161018b8..863b7cbb12 100644
--- a/indra/newview/llfloaterwindowsize.cpp
+++ b/indra/newview/llfloaterwindowsize.cpp
@@ -34,18 +34,16 @@
#include "llcombobox.h"
#include "llfloater.h"
#include "llfloaterreg.h"
+#include "llregex.h"
#include "lluictrl.h"
-// System libraries
-#include <boost/regex.hpp>
-
// Extract from strings of the form "<width> x <height>", e.g. "640 x 480".
bool extractWindowSizeFromString(const std::string& instr, U32 *width, U32 *height)
{
boost::cmatch what;
// matches (any number)(any non-number)(any number)
const boost::regex expression("([0-9]+)[^0-9]+([0-9]+)");
- if (boost::regex_match(instr.c_str(), what, expression))
+ if (ll_regex_match(instr.c_str(), what, expression))
{
*width = atoi(what[1].first);
*height = atoi(what[2].first);
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 4ed802138d..9d49c30a49 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -105,6 +105,9 @@ LLHUDNameTag::LLHUDNameTag(const U8 type)
{
LLPointer<LLHUDNameTag> ptr(this);
sTextObjects.insert(ptr);
+
+ mRoundedRectImgp = LLUI::getUIImage("Rounded_Rect");
+ mRoundedRectTopImgp = LLUI::getUIImage("Rounded_Rect_Top");
}
LLHUDNameTag::~LLHUDNameTag()
@@ -274,9 +277,6 @@ void LLHUDNameTag::renderText(BOOL for_select)
mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));
- // *TODO: cache this image
- LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Rect");
-
// *TODO: make this a per-text setting
LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");
bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
@@ -306,17 +306,16 @@ void LLHUDNameTag::renderText(BOOL for_select)
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
LLRect screen_rect;
screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight)));
- imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
+ mRoundedRectImgp->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
if (mLabelSegments.size())
{
- LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");
LLRect label_top_rect = screen_rect;
const S32 label_height = ll_round((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
label_top_rect.mBottom = label_top_rect.mTop - label_height;
LLColor4 label_top_color = text_color;
label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
- rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
+ mRoundedRectTopImgp->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
}
F32 y_offset = (F32)mOffsetY;
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 20272a8232..7577dd5de6 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -40,8 +40,8 @@
#include <set>
#include <vector>
-class LLDrawable;
class LLHUDNameTag;
+class LLUIImage;
struct llhudnametag_further_away
{
@@ -171,6 +171,8 @@ private:
EVertAlignment mVertAlignment;
S32 mLOD;
BOOL mHidden;
+ LLPointer<LLUIImage> mRoundedRectImgp;
+ LLPointer<LLUIImage> mRoundedRectTopImgp;
static BOOL sDisplayText ;
static std::set<LLPointer<LLHUDNameTag> > sTextObjects;
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 72d28a3d44..7c957ac712 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -138,9 +138,6 @@ void LLHUDText::renderText()
mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));
- // *TODO: cache this image
- LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
-
// *TODO: make this a per-text setting
LLColor4 bg_color = LLUIColorTable::instance().getColor("ObjectBubbleColor");
bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 1e43e4ea3a..0524313a5c 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -42,6 +42,7 @@
#include "llnotificationsutil.h"
#include "llnotificationmanager.h"
#include "llpanelgroup.h"
+#include "llregex.h"
#include "llregionhandle.h"
#include "llsdserialize.h"
#include "llslurl.h"
@@ -55,7 +56,6 @@
#include "llviewerregion.h"
#include "llvoavatarself.h"
-#include <boost/regex.hpp>
#include "boost/lexical_cast.hpp"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -122,7 +122,7 @@ static std::string clean_name_from_task_im(const std::string& msg,
boost::smatch match;
static const boost::regex returned_exp(
"(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)");
- if (boost::regex_match(msg, match, returned_exp))
+ if (ll_regex_match(msg, match, returned_exp))
{
// match objects are 1-based for groups
std::string final = match[1].str();
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 8b61e6c61a..fc8179f3b4 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3970,6 +3970,12 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
const LLUUID &favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
const LLUUID &marketplace_listings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID &outfits_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
+
+ if (outfits_id == mUUID)
+ {
+ items.push_back(std::string("New Outfit"));
+ }
if (lost_and_found_id == mUUID)
{
@@ -4068,7 +4074,8 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
// Not sure what the right thing is to do here.
if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))
{
- if (!isInboxFolder()) // don't allow creation in inbox
+ if (!isInboxFolder() // don't allow creation in inbox
+ && outfits_id != mUUID)
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 411311bbea..3b5ba24b9f 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -36,13 +36,14 @@
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryfunctions.h"
#include "llmarketplacefunctions.h"
+#include "llregex.h"
#include "llviewercontrol.h"
#include "llfolderview.h"
#include "llinventorybridge.h"
#include "llviewerfoldertype.h"
#include "llradiogroup.h"
#include "llstartup.h"
-#include <boost/regex.hpp>
+
// linden library includes
#include "llclipboard.h"
#include "lltrans.h"
@@ -879,7 +880,7 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
boost::regex mPattern = boost::regex("\"\\s*([^<]*)?\\s*\"",
boost::regex::perl | boost::regex::icase);
boost::match_results<std::string::const_iterator> matches;
- mExactToken = (boost::regex_match(filter_sub_string_new, matches, mPattern) && matches[1].matched)
+ mExactToken = (ll_regex_match(filter_sub_string_new, matches, mPattern) && matches[1].matched)
? matches[1]
: LLStringUtil::null;
if ((old_token.empty() && !mExactToken.empty())
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 28db6a5808..ba453471c6 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -487,7 +487,8 @@ const LLUUID LLInventoryModel::findCategoryUUIDForTypeInRoot(
S32 count = cats->size();
for(S32 i = 0; i < count; ++i)
{
- if(cats->at(i)->getPreferredType() == preferred_type)
+ LLViewerInventoryCategory* p_cat = cats->at(i);
+ if(p_cat && p_cat->getPreferredType() == preferred_type)
{
const LLUUID& folder_id = cats->at(i)->getUUID();
if (rv.isNull() || folder_id < rv)
@@ -1659,9 +1660,18 @@ void LLInventoryModel::notifyObservers()
iter = mObservers.upper_bound(observer);
}
- mModifyMask = LLInventoryObserver::NONE;
+ // If there were any changes that arrived during notifyObservers,
+ // shedule them for next loop
+ mModifyMask = mModifyMaskBacklog;
mChangedItemIDs.clear();
+ mChangedItemIDs.insert(mChangedItemIDsBacklog.begin(), mChangedItemIDsBacklog.end());
mAddedItemIDs.clear();
+ mAddedItemIDs.insert(mAddedItemIDsBacklog.begin(), mAddedItemIDsBacklog.end());
+
+ mModifyMaskBacklog = LLInventoryObserver::NONE;
+ mChangedItemIDsBacklog.clear();
+ mAddedItemIDsBacklog.clear();
+
mIsNotifyObservers = FALSE;
}
@@ -1673,8 +1683,10 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
{
// Something marked an item for change within a call to notifyObservers
// (which is in the process of processing the list of items marked for change).
- // This means the change may fail to be processed.
- LL_WARNS(LOG_INV) << "Adding changed mask within notify observers! Change will likely be lost." << LL_ENDL;
+ // This means the change will have to be processed later.
+ // It's preferable for this not to happen, but it's not an issue unless code
+ // specifically wants to notifyObservers immediately (changes won't happen untill later)
+ LL_WARNS(LOG_INV) << "Adding changed mask within notify observers! Change's processing will be performed on idle." << LL_ENDL;
LLViewerInventoryItem *item = getItem(referent);
if (item)
{
@@ -1689,17 +1701,40 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
}
}
}
-
- mModifyMask |= mask;
+
+ if (mIsNotifyObservers)
+ {
+ mModifyMaskBacklog |= mask;
+ }
+ else
+ {
+ mModifyMask |= mask;
+ }
+
if (referent.notNull() && (mChangedItemIDs.find(referent) == mChangedItemIDs.end()))
{
- mChangedItemIDs.insert(referent);
+ if (mIsNotifyObservers)
+ {
+ mChangedItemIDsBacklog.insert(referent);
+ }
+ else
+ {
+ mChangedItemIDs.insert(referent);
+ }
+
update_marketplace_category(referent, false);
- if (mask & LLInventoryObserver::ADD)
- {
- mAddedItemIDs.insert(referent);
- }
+ if (mask & LLInventoryObserver::ADD)
+ {
+ if (mIsNotifyObservers)
+ {
+ mAddedItemIDsBacklog.insert(referent);
+ }
+ else
+ {
+ mAddedItemIDs.insert(referent);
+ }
+ }
// Update all linked items. Starting with just LABEL because I'm
// not sure what else might need to be accounted for this.
@@ -2660,7 +2695,10 @@ void LLInventoryModel::createCommonSystemCategories()
gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD,true);
gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS,true);
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, true);
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, true); // folder should exist before user tries to 'landmark this'
gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS, true);
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, true);
}
struct LLUUIDAndName
@@ -3705,17 +3743,18 @@ void LLInventoryModel::dumpInventory() const
// returning an overall good/bad flag.
bool LLInventoryModel::validate() const
{
- bool valid = true;
+ const S32 MAX_VERBOSE_ERRORS = 40; // too many errors can cause disconect or freeze
+ S32 error_count = 0;
if (getRootFolderID().isNull())
{
LL_WARNS() << "no root folder id" << LL_ENDL;
- valid = false;
+ error_count++;
}
if (getLibraryRootFolderID().isNull())
{
LL_WARNS() << "no root folder id" << LL_ENDL;
- valid = false;
+ error_count++;
}
if (mCategoryMap.size() + 1 != mParentChildCategoryTree.size())
@@ -3723,7 +3762,7 @@ bool LLInventoryModel::validate() const
// ParentChild should be one larger because of the special entry for null uuid.
LL_INFOS() << "unexpected sizes: cat map size " << mCategoryMap.size()
<< " parent/child " << mParentChildCategoryTree.size() << LL_ENDL;
- valid = false;
+ error_count++;
}
S32 cat_lock = 0;
S32 item_lock = 0;
@@ -3735,23 +3774,32 @@ bool LLInventoryModel::validate() const
const LLViewerInventoryCategory *cat = cit->second;
if (!cat)
{
- LL_WARNS() << "invalid cat" << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "invalid cat" << LL_ENDL;
+ }
+ error_count++;
continue;
}
if (cat_id != cat->getUUID())
{
- LL_WARNS() << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
+ }
+ error_count++;
}
if (cat->getParentUUID().isNull())
{
if (cat_id != getRootFolderID() && cat_id != getLibraryRootFolderID())
{
- LL_WARNS() << "cat " << cat_id << " has no parent, but is not root ("
- << getRootFolderID() << ") or library root ("
- << getLibraryRootFolderID() << ")" << LL_ENDL;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "cat " << cat_id << " has no parent, but is not root ("
+ << getRootFolderID() << ") or library root ("
+ << getLibraryRootFolderID() << ")" << LL_ENDL;
+ }
}
}
cat_array_t* cats;
@@ -3759,8 +3807,11 @@ bool LLInventoryModel::validate() const
getDirectDescendentsOf(cat_id,cats,items);
if (!cats || !items)
{
- LL_WARNS() << "invalid direct descendents for " << cat_id << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "invalid direct descendents for " << cat_id << LL_ENDL;
+ }
+ error_count++;
continue;
}
if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
@@ -3769,12 +3820,15 @@ bool LLInventoryModel::validate() const
}
else if (cats->size() + items->size() != cat->getDescendentCount())
{
- LL_WARNS() << "invalid desc count for " << cat_id << " name [" << cat->getName()
- << "] parent " << cat->getParentUUID()
- << " cached " << cat->getDescendentCount()
- << " expected " << cats->size() << "+" << items->size()
- << "=" << cats->size() +items->size() << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "invalid desc count for " << cat_id << " name [" << cat->getName()
+ << "] parent " << cat->getParentUUID()
+ << " cached " << cat->getDescendentCount()
+ << " expected " << cats->size() << "+" << items->size()
+ << "=" << cats->size() + items->size() << LL_ENDL;
+ }
+ error_count++;
}
if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
{
@@ -3794,8 +3848,11 @@ bool LLInventoryModel::validate() const
if (!item)
{
- LL_WARNS() << "null item at index " << i << " for cat " << cat_id << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "null item at index " << i << " for cat " << cat_id << LL_ENDL;
+ }
+ error_count++;
continue;
}
@@ -3803,10 +3860,13 @@ bool LLInventoryModel::validate() const
if (item->getParentUUID() != cat_id)
{
- LL_WARNS() << "wrong parent for " << item_id << " found "
- << item->getParentUUID() << " expected " << cat_id
- << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "wrong parent for " << item_id << " found "
+ << item->getParentUUID() << " expected " << cat_id
+ << LL_ENDL;
+ }
+ error_count++;
}
@@ -3814,17 +3874,24 @@ bool LLInventoryModel::validate() const
item_map_t::const_iterator it = mItemMap.find(item_id);
if (it == mItemMap.end())
{
- LL_WARNS() << "item " << item_id << " found as child of "
- << cat_id << " but not in top level mItemMap" << LL_ENDL;
- valid = false;
+
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "item " << item_id << " found as child of "
+ << cat_id << " but not in top level mItemMap" << LL_ENDL;
+ }
+ error_count++;
}
else
{
LLViewerInventoryItem *top_item = it->second;
if (top_item != item)
{
- LL_WARNS() << "item mismatch, item_id " << item_id
- << " top level entry is different, uuid " << top_item->getUUID() << LL_ENDL;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "item mismatch, item_id " << item_id
+ << " top level entry is different, uuid " << top_item->getUUID() << LL_ENDL;
+ }
}
}
@@ -3833,19 +3900,25 @@ bool LLInventoryModel::validate() const
bool found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
if (!found)
{
- LL_WARNS() << "unable to find topmost ancestor for " << item_id << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "unable to find topmost ancestor for " << item_id << LL_ENDL;
+ }
+ error_count++;
}
else
{
if (topmost_ancestor_id != getRootFolderID() &&
topmost_ancestor_id != getLibraryRootFolderID())
{
- LL_WARNS() << "unrecognized top level ancestor for " << item_id
- << " got " << topmost_ancestor_id
- << " expected " << getRootFolderID()
- << " or " << getLibraryRootFolderID() << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "unrecognized top level ancestor for " << item_id
+ << " got " << topmost_ancestor_id
+ << " expected " << getRootFolderID()
+ << " or " << getLibraryRootFolderID() << LL_ENDL;
+ }
+ error_count++;
}
}
}
@@ -3859,9 +3932,12 @@ bool LLInventoryModel::validate() const
getDirectDescendentsOf(parent_id,cats,items);
if (!cats)
{
- LL_WARNS() << "cat " << cat_id << " name [" << cat->getName()
- << "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "cat " << cat_id << " name [" << cat->getName()
+ << "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
+ }
+ error_count++;
}
else
{
@@ -3877,8 +3953,11 @@ bool LLInventoryModel::validate() const
}
if (!found)
{
- LL_WARNS() << "cat " << cat_id << " name [" << cat->getName()
- << "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "cat " << cat_id << " name [" << cat->getName()
+ << "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
+ }
}
}
}
@@ -3890,24 +3969,33 @@ bool LLInventoryModel::validate() const
LLViewerInventoryItem *item = iit->second;
if (item->getUUID() != item_id)
{
- LL_WARNS() << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL;
- valid = false;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL;
+ }
+ error_count++;
}
const LLUUID& parent_id = item->getParentUUID();
if (parent_id.isNull())
{
- LL_WARNS() << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
+ }
}
- else
+ else if (error_count < MAX_VERBOSE_ERRORS)
{
cat_array_t* cats;
item_array_t* items;
getDirectDescendentsOf(parent_id,cats,items);
if (!items)
{
- LL_WARNS() << "item " << item_id << " name [" << item->getName()
- << "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "item " << item_id << " name [" << item->getName()
+ << "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
+ }
}
else
{
@@ -3922,63 +4010,70 @@ bool LLInventoryModel::validate() const
}
if (!found)
{
- LL_WARNS() << "item " << item_id << " name [" << item->getName()
- << "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ LL_WARNS() << "item " << item_id << " name [" << item->getName()
+ << "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
+ }
}
}
}
- // Link checking
- if (item->getIsLinkType())
- {
- const LLUUID& link_id = item->getUUID();
- const LLUUID& target_id = item->getLinkedUUID();
- LLViewerInventoryItem *target_item = getItem(target_id);
- LLViewerInventoryCategory *target_cat = getCategory(target_id);
- // Linked-to UUID should have back reference to this link.
- if (!hasBacklinkInfo(link_id, target_id))
- {
- LL_WARNS() << "link " << item->getUUID() << " type " << item->getActualType()
- << " missing backlink info at target_id " << target_id
- << LL_ENDL;
- }
- // Links should have referents.
- if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
- {
- LL_WARNS() << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- }
- else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
- {
- LL_WARNS() << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- }
- if (target_item && target_item->getIsLinkType())
- {
- LL_WARNS() << "link " << item->getName() << " references a link item "
- << target_item->getName() << " " << target_item->getUUID() << LL_ENDL;
- }
- // Links should not have backlinks.
- std::pair<backlink_mmap_t::const_iterator, backlink_mmap_t::const_iterator> range = mBacklinkMMap.equal_range(link_id);
- if (range.first != range.second)
- {
- LL_WARNS() << "Link item " << item->getName() << " has backlinks!" << LL_ENDL;
- }
- }
- else
- {
- // Check the backlinks of a non-link item.
- const LLUUID& target_id = item->getUUID();
- std::pair<backlink_mmap_t::const_iterator, backlink_mmap_t::const_iterator> range = mBacklinkMMap.equal_range(target_id);
- for (backlink_mmap_t::const_iterator it = range.first; it != range.second; ++it)
- {
- const LLUUID& link_id = it->second;
- LLViewerInventoryItem *link_item = getItem(link_id);
- if (!link_item || !link_item->getIsLinkType())
- {
- LL_WARNS() << "invalid backlink from target " << item->getName() << " to " << link_id << LL_ENDL;
- }
- }
- }
+ // Link checking
+ if (error_count < MAX_VERBOSE_ERRORS)
+ {
+ if (item->getIsLinkType())
+ {
+ const LLUUID& link_id = item->getUUID();
+ const LLUUID& target_id = item->getLinkedUUID();
+ LLViewerInventoryItem *target_item = getItem(target_id);
+ LLViewerInventoryCategory *target_cat = getCategory(target_id);
+ // Linked-to UUID should have back reference to this link.
+ if (!hasBacklinkInfo(link_id, target_id))
+ {
+ LL_WARNS() << "link " << item->getUUID() << " type " << item->getActualType()
+ << " missing backlink info at target_id " << target_id
+ << LL_ENDL;
+ }
+ // Links should have referents.
+ if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
+ {
+ LL_WARNS() << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
+ }
+ else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
+ {
+ LL_WARNS() << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
+ }
+ if (target_item && target_item->getIsLinkType())
+ {
+ LL_WARNS() << "link " << item->getName() << " references a link item "
+ << target_item->getName() << " " << target_item->getUUID() << LL_ENDL;
+ }
+
+ // Links should not have backlinks.
+ std::pair<backlink_mmap_t::const_iterator, backlink_mmap_t::const_iterator> range = mBacklinkMMap.equal_range(link_id);
+ if (range.first != range.second)
+ {
+ LL_WARNS() << "Link item " << item->getName() << " has backlinks!" << LL_ENDL;
+ }
+ }
+ else
+ {
+ // Check the backlinks of a non-link item.
+ const LLUUID& target_id = item->getUUID();
+ std::pair<backlink_mmap_t::const_iterator, backlink_mmap_t::const_iterator> range = mBacklinkMMap.equal_range(target_id);
+ for (backlink_mmap_t::const_iterator it = range.first; it != range.second; ++it)
+ {
+ const LLUUID& link_id = it->second;
+ LLViewerInventoryItem *link_item = getItem(link_id);
+ if (!link_item || !link_item->getIsLinkType())
+ {
+ LL_WARNS() << "invalid backlink from target " << item->getName() << " to " << link_id << LL_ENDL;
+ }
+ }
+ }
+ }
}
if (cat_lock > 0 || item_lock > 0)
@@ -3995,9 +4090,9 @@ bool LLInventoryModel::validate() const
LL_INFOS() << "Found " << version_unknown_count << " cats with unknown version" << LL_ENDL;
}
- LL_INFOS() << "Validate done, valid = " << (U32) valid << LL_ENDL;
+ LL_INFOS() << "Validate done, found " << error_count << " errors" << LL_ENDL;
- return valid;
+ return error_count == 0;
}
///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index a4326aaeed..4dcd9332be 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -538,6 +538,10 @@ private:
U32 mModifyMask;
changed_items_t mChangedItemIDs;
changed_items_t mAddedItemIDs;
+ // Fallback when notifyObservers is in progress
+ U32 mModifyMaskBacklog;
+ changed_items_t mChangedItemIDsBacklog;
+ changed_items_t mAddedItemIDsBacklog;
//--------------------------------------------------------------------
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 3608f9e23f..05d9fec701 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -44,6 +44,7 @@
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llnotificationsutil.h"
+#include "llpanelmaininventory.h"
#include "llpreview.h"
#include "llsidepanelinventory.h"
#include "llstartup.h"
@@ -1614,7 +1615,7 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
- if (main_panel && !in_inbox)
+ if (!in_inbox && (main_panel || !sidepanel_inventory->getMainInventoryPanel()->isRecentItemsPanelSelected()))
{
sidepanel_inventory->selectAllItemsPanel();
}
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index 543d2a087f..9106d4e986 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -74,6 +74,16 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
{
return NULL;
}
+
+ if (cb)
+ {
+ // Multiple different sources can request same landmark,
+ // mLoadedCallbackMap is a multimap that allows multiple pairs with same key
+ // Todo: this might need to be improved to not hold identical callbacks multiple times
+ loaded_callback_map_t::value_type vt(asset_uuid, cb);
+ mLoadedCallbackMap.insert(vt);
+ }
+
if ( mWaitList.find(asset_uuid) != mWaitList.end() )
{
// Landmark is sheduled for download, but not requested yet
@@ -89,12 +99,6 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
return NULL;
}
}
-
- if (cb)
- {
- loaded_callback_map_t::value_type vt(asset_uuid, cb);
- mLoadedCallbackMap.insert(vt);
- }
if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)
{
@@ -132,36 +136,49 @@ void LLLandmarkList::processGetAssetReply(
LLVFile file(vfs, uuid, type);
S32 file_length = file.getSize();
- std::vector<char> buffer(file_length + 1);
- file.read( (U8*)&buffer[0], file_length);
- buffer[ file_length ] = 0;
+ if (file_length > 0)
+ {
+ std::vector<char> buffer(file_length + 1);
+ file.read((U8*)&buffer[0], file_length);
+ buffer[file_length] = 0;
- LLLandmark* landmark = LLLandmark::constructFromString(&buffer[0]);
- if (landmark)
- {
- gLandmarkList.mList[ uuid ] = landmark;
- gLandmarkList.mRequestedList.erase(uuid);
-
- LLVector3d pos;
- if(!landmark->getGlobalPos(pos))
- {
- LLUUID region_id;
- if(landmark->getRegionID(region_id))
- {
- LLLandmark::requestRegionHandle(
- gMessageSystem,
- gAgent.getRegionHost(),
- region_id,
- boost::bind(&LLLandmarkList::onRegionHandle, &gLandmarkList, uuid));
- }
-
- // the callback will be called when we get the region handle.
- }
- else
- {
- gLandmarkList.makeCallbacks(uuid);
- }
- }
+ LLLandmark* landmark = LLLandmark::constructFromString(&buffer[0], buffer.size());
+ if (landmark)
+ {
+ gLandmarkList.mList[uuid] = landmark;
+ gLandmarkList.mRequestedList.erase(uuid);
+
+ LLVector3d pos;
+ if (!landmark->getGlobalPos(pos))
+ {
+ LLUUID region_id;
+ if (landmark->getRegionID(region_id))
+ {
+ LLLandmark::requestRegionHandle(
+ gMessageSystem,
+ gAgent.getRegionHost(),
+ region_id,
+ boost::bind(&LLLandmarkList::onRegionHandle, &gLandmarkList, uuid));
+ }
+
+ // the callback will be called when we get the region handle.
+ }
+ else
+ {
+ gLandmarkList.makeCallbacks(uuid);
+ }
+ }
+ else
+ {
+ // failed to parse, shouldn't happen
+ gLandmarkList.eraseCallbacks(uuid);
+ }
+ }
+ else
+ {
+ // got a good status, but no file, shouldn't happen
+ gLandmarkList.eraseCallbacks(uuid);
+ }
}
else
{
@@ -179,7 +196,7 @@ void LLLandmarkList::processGetAssetReply(
gLandmarkList.mBadList.insert(uuid);
gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests
- // todo: this should clean mLoadedCallbackMap!
+ gLandmarkList.eraseCallbacks(uuid);
}
// getAssetData can fire callback immediately, causing
@@ -223,32 +240,39 @@ BOOL LLLandmarkList::assetExists(const LLUUID& asset_uuid)
void LLLandmarkList::onRegionHandle(const LLUUID& landmark_id)
{
LLLandmark* landmark = getAsset(landmark_id);
-
- if (!landmark)
- {
- LL_WARNS() << "Got region handle but the landmark not found." << LL_ENDL;
- return;
- }
+ if (!landmark)
+ {
+ LL_WARNS() << "Got region handle but the landmark " << landmark_id << " not found." << LL_ENDL;
+ eraseCallbacks(landmark_id);
+ return;
+ }
// Calculate landmark global position.
// This should succeed since the region handle is available.
LLVector3d pos;
if (!landmark->getGlobalPos(pos))
{
- LL_WARNS() << "Got region handle but the landmark global position is still unknown." << LL_ENDL;
- return;
+ LL_WARNS() << "Got region handle but the landmark " << landmark_id << " global position is still unknown." << LL_ENDL;
+ eraseCallbacks(landmark_id);
+ return;
}
+ // Call this even if no landmark exists to clean mLoadedCallbackMap
makeCallbacks(landmark_id);
}
+void LLLandmarkList::eraseCallbacks(const LLUUID& landmark_id)
+{
+ mLoadedCallbackMap.erase(landmark_id);
+}
+
void LLLandmarkList::makeCallbacks(const LLUUID& landmark_id)
{
LLLandmark* landmark = getAsset(landmark_id);
if (!landmark)
{
- LL_WARNS() << "Landmark to make callbacks for not found." << LL_ENDL;
+ LL_WARNS() << "Landmark " << landmark_id << " to make callbacks for not found." << LL_ENDL;
}
// make all the callbacks here.
diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h
index 2e7bd25610..4f3b11660d 100644
--- a/indra/newview/lllandmarklist.h
+++ b/indra/newview/lllandmarklist.h
@@ -65,6 +65,7 @@ public:
protected:
void onRegionHandle(const LLUUID& landmark_id);
+ void eraseCallbacks(const LLUUID& landmark_id);
void makeCallbacks(const LLUUID& landmark_id);
typedef std::map<LLUUID, LLLandmark*> landmark_list_t;
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index eebc2486a2..fb9885b454 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -30,6 +30,7 @@
#include "llagentui.h"
#include "llavatarnamecache.h"
#include "lllogchat.h"
+#include "llregex.h"
#include "lltrans.h"
#include "llviewercontrol.h"
@@ -40,7 +41,6 @@
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/replace.hpp>
-#include <boost/regex.hpp>
#include <boost/regex/v4/match_results.hpp>
#include <boost/foreach.hpp>
@@ -250,8 +250,8 @@ std::string LLLogChat::makeLogFileName(std::string filename)
**/
boost::match_results<std::string::const_iterator> matches;
- bool inboundConf = boost::regex_match(filename, matches, INBOUND_CONFERENCE);
- bool outboundConf = boost::regex_match(filename, matches, OUTBOUND_CONFERENCE);
+ bool inboundConf = ll_regex_match(filename, matches, INBOUND_CONFERENCE);
+ bool outboundConf = ll_regex_match(filename, matches, OUTBOUND_CONFERENCE);
if (!(inboundConf || outboundConf))
{
if( gSavedPerAccountSettings.getBOOL("LogFileNamewithDate") )
@@ -837,7 +837,7 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
{
//matching a timestamp
boost::match_results<std::string::const_iterator> matches;
- if (boost::regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP))
+ if (ll_regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP))
{
result = true;
}
@@ -917,7 +917,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
//matching a timestamp
boost::match_results<std::string::const_iterator> matches;
- if (!boost::regex_match(raw, matches, TIMESTAMP_AND_STUFF)) return false;
+ if (!ll_regex_match(raw, matches, TIMESTAMP_AND_STUFF)) return false;
bool has_timestamp = matches[IDX_TIMESTAMP].matched;
if (has_timestamp)
@@ -950,7 +950,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
//matching a name and a text
std::string stuff = matches[IDX_STUFF];
boost::match_results<std::string::const_iterator> name_and_text;
- if (!boost::regex_match(stuff, name_and_text, NAME_AND_TEXT)) return false;
+ if (!ll_regex_match(stuff, name_and_text, NAME_AND_TEXT)) return false;
bool has_name = name_and_text[IDX_NAME].matched;
std::string name = LLURI::unescape(name_and_text[IDX_NAME]);
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 958c76f261..bd24c47a4f 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -31,6 +31,7 @@
#include "lluictrl.h"
#include "llframetimer.h"
+#include "llnotificationptr.h"
class LLViewBorder;
class LLUICtrlFactory;
@@ -145,7 +146,7 @@ public:
void setTextureSize(S32 width, S32 height);
- void showNotification(boost::shared_ptr<class LLNotification> notify);
+ void showNotification(LLNotificationPtr notify);
void hideNotification();
void setTrustedContent(bool trusted);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 3e8731dfe6..2c1c1191da 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -881,7 +881,7 @@ void LLMeshRepoThread::run()
LL_WARNS(LOG_MESH) << "Convex decomposition unable to be loaded. Expect severe problems." << LL_ENDL;
}
- while (!LLApp::isQuitting())
+ while (!LLApp::isExiting())
{
// *TODO: Revise sleep/wake strategy and try to move away
// from polling operations in this thread. We can sleep
@@ -898,7 +898,7 @@ void LLMeshRepoThread::run()
mSignal->wait();
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
break;
}
@@ -1168,7 +1168,7 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{
- if (!LLAppViewer::isQuitting())
+ if (!LLAppViewer::isExiting())
{
loadMeshLOD(mesh_params, lod);
}
@@ -2654,7 +2654,7 @@ void LLMeshUploadThread::doWholeModelUpload()
LL_DEBUGS(LOG_MESH) << "POST request issued." << LL_ENDL;
mHttpRequest->update(0);
- while (! LLApp::isQuitting() && ! finished() && ! isDiscarded())
+ while (! LLApp::isExiting() && ! finished() && ! isDiscarded())
{
ms_sleep(sleep_time);
sleep_time = llmin(250U, sleep_time + sleep_time);
@@ -2703,7 +2703,7 @@ void LLMeshUploadThread::requestWholeModelFee()
U32 sleep_time(10);
mHttpRequest->update(0);
- while (! LLApp::isQuitting() && ! finished() && ! isDiscarded())
+ while (! LLApp::isExiting() && ! finished() && ! isDiscarded())
{
ms_sleep(sleep_time);
sleep_time = llmin(250U, sleep_time + sleep_time);
@@ -3149,7 +3149,7 @@ common_exit:
LLMeshHeaderHandler::~LLMeshHeaderHandler()
{
- if (!LLApp::isQuitting())
+ if (!LLApp::isExiting())
{
if (! mProcessed)
{
@@ -3292,7 +3292,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
LLMeshLODHandler::~LLMeshLODHandler()
{
- if (! LLApp::isQuitting())
+ if (! LLApp::isExiting())
{
if (! mProcessed)
{
@@ -3553,7 +3553,7 @@ void LLMeshRepository::shutdown()
mUploads[i]->discard() ; //discard the uploading requests.
}
- mThread->mSignal->signal();
+ mThread->mSignal->broadcast();
while (!mThread->isStopped())
{
@@ -4682,7 +4682,8 @@ void LLPhysicsDecomp::shutdown()
if (mSignal)
{
mQuitting = true;
- mSignal->signal();
+ // There is only one wait(), but just in case 'broadcast'
+ mSignal->broadcast();
while (!isStopped())
{
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 272e7ae351..c1b622ffff 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -67,6 +67,7 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
mOutfitsObserver(NULL),
mScrollPanel(NULL),
mGalleryPanel(NULL),
+ mLastRowPanel(NULL),
mGalleryCreated(false),
mRowCount(0),
mItemsAddedCount(0),
@@ -166,9 +167,7 @@ bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
std::string name1 = item1->getItemName();
std::string name2 = item2->getItemName();
- LLStringUtil::toUpper(name1);
- LLStringUtil::toUpper(name2);
- return name1 < name2;
+ return (LLStringUtil::compareDict(name1, name2) < 0);
}
else
{
@@ -241,7 +240,15 @@ void LLOutfitGallery::removeLastRow()
mGalleryPanel->removeChild(mLastRowPanel);
mUnusedRowPanels.push_back(mLastRowPanel);
mRowPanels.pop_back();
- mLastRowPanel = mRowPanels.back();
+ if (mRowPanels.size() > 0)
+ {
+ // Just removed last row
+ mLastRowPanel = mRowPanels.back();
+ }
+ else
+ {
+ mLastRowPanel = NULL;
+ }
}
LLPanel* LLOutfitGallery::addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap)
@@ -1111,7 +1118,7 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
}
}
- if (mGalleryCreated && !LLApp::isQuitting())
+ if (mGalleryCreated && !LLApp::isExiting())
{
reArrangeRows();
}
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 71ab826e1c..423e57978a 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -59,10 +59,7 @@ bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LL
std::string name1 = tab1->getTitle();
std::string name2 = tab2->getTitle();
- LLStringUtil::toUpper(name1);
- LLStringUtil::toUpper(name2);
-
- return name1 < name2;
+ return (LLStringUtil::compareDict(name1, name2) < 0);
}
struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLAccordionCtrlTab::Params>
diff --git a/indra/newview/llpanelexperiencepicker.cpp b/indra/newview/llpanelexperiencepicker.cpp
index 80aeee6da1..6dfdbaf63f 100644
--- a/indra/newview/llpanelexperiencepicker.cpp
+++ b/indra/newview/llpanelexperiencepicker.cpp
@@ -41,8 +41,8 @@
#include "llcombobox.h"
#include "llviewercontrol.h"
#include "llfloater.h"
+#include "llregex.h"
#include "lltrans.h"
-#include <boost/regex.hpp>
#define BTN_FIND "find"
#define BTN_OK "ok_btn"
@@ -116,7 +116,7 @@ void LLPanelExperiencePicker::onBtnFind()
boost::cmatch what;
std::string text = getChild<LLUICtrl>(TEXT_EDIT)->getValue().asString();
const boost::regex expression("secondlife:///app/experience/[\\da-f-]+/profile");
- if (boost::regex_match(text.c_str(), what, expression))
+ if (ll_regex_match(text.c_str(), what, expression))
{
LLURI uri(text);
LLSD path_array = uri.pathArray();
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 3964dc075c..381b80fb66 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -254,7 +254,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLLineEditor* password_edit(getChild<LLLineEditor>("password_edit"));
password_edit->setKeystrokeCallback(onPassKey, this);
// STEAM-14: When user presses Enter with this field in focus, initiate login
- password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, false));
// change z sort of clickable text to be behind buttons
sendChildToBack(getChildView("forgot_password_text"));
@@ -265,7 +265,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
{
LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
- favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false));
favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
@@ -458,6 +458,9 @@ void LLPanelLogin::addFavoritesToStartLocation()
if (combo->getValue().asString().empty())
{
combo->selectFirstItem();
+ // Value 'home' or 'last' should have been taken from NextLoginLocation
+ // but NextLoginLocation was not set, so init it from combo explicitly
+ onLocationSLURL();
}
}
@@ -1004,12 +1007,15 @@ void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
// Protected methods
//---------------------------------------------------------------------------
// static
-void LLPanelLogin::onClickConnect(void *)
+void LLPanelLogin::onClickConnect(bool commit_fields)
{
if (sInstance && sInstance->mCallback)
{
- // JC - Make sure the fields all get committed.
- sInstance->setFocus(FALSE);
+ if (commit_fields)
+ {
+ // JC - Make sure the fields all get committed.
+ sInstance->setFocus(FALSE);
+ }
LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
LLSD combo_val = combo->getSelectedValue();
@@ -1132,7 +1138,7 @@ void LLPanelLogin::onUserListCommit(void*)
}
else
{
- onClickConnect(NULL);
+ onClickConnect();
}
}
}
@@ -1364,6 +1370,7 @@ void LLPanelLogin::onSelectServer()
{
// the grid specified by the location is not this one, so clear the combo
location_combo->setCurrentByIndex(0); // last location on the new grid
+ onLocationSLURL();
}
}
break;
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 788c269ffd..c5e6b41def 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -99,7 +99,7 @@ private:
static void setFields(LLPointer<LLCredential> credential);
- static void onClickConnect(void*);
+ static void onClickConnect(bool commit_fields = true);
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index e9c9c451a2..1a1792fb60 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -62,15 +62,11 @@
const std::string FILTERS_FILENAME("filters.xml");
-static LLPanelInjector<LLPanelMainInventory> t_inventory("panel_main_inventory");
+const std::string ALL_ITEMS("All Items");
+const std::string RECENT_ITEMS("Recent Items");
+const std::string WORN_ITEMS("Worn Items");
-void on_file_loaded_for_save(BOOL success,
- LLViewerFetchedTexture *src_vi,
- LLImageRaw* src,
- LLImageRaw* aux_src,
- S32 discard_level,
- BOOL final,
- void* userdata);
+static LLPanelInjector<LLPanelMainInventory> t_inventory("panel_main_inventory");
///----------------------------------------------------------------------------
/// LLFloaterInventoryFinder
@@ -149,7 +145,7 @@ BOOL LLPanelMainInventory::postBuild()
//panel->getFilter().markDefault();
// Set up the default inv. panel/filter settings.
- mActivePanel = getChild<LLInventoryPanel>("All Items");
+ mActivePanel = getChild<LLInventoryPanel>(ALL_ITEMS);
if (mActivePanel)
{
// "All Items" is the previous only view, so it gets the InventorySortOrder
@@ -159,7 +155,7 @@ BOOL LLPanelMainInventory::postBuild()
mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
mResortActivePanel = true;
}
- LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
+ LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>(RECENT_ITEMS);
if (recent_items_panel)
{
// assign default values until we will be sure that we have setting to restore
@@ -174,7 +170,7 @@ BOOL LLPanelMainInventory::postBuild()
recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
}
- mWornItemsPanel = getChild<LLInventoryPanel>("Worn Items");
+ mWornItemsPanel = getChild<LLInventoryPanel>(WORN_ITEMS);
if (mWornItemsPanel)
{
U32 filter_types = 0x0;
@@ -271,7 +267,7 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
// for example, LLParamSDParser doesn't know about U64,
// so some FilterOps params should be revised.
LLSD filterRoot;
- LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
+ LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>(ALL_ITEMS);
if (all_items_panel)
{
LLSD filterState;
@@ -285,7 +281,7 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
}
}
- LLInventoryPanel* panel = findChild<LLInventoryPanel>("Recent Items");
+ LLInventoryPanel* panel = findChild<LLInventoryPanel>(RECENT_ITEMS);
if (panel)
{
LLSD filterState;
@@ -316,7 +312,7 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel()
{
- return getChild<LLInventoryPanel>("All Items");
+ return getChild<LLInventoryPanel>(ALL_ITEMS);
}
void LLPanelMainInventory::selectAllItemsPanel()
@@ -324,6 +320,11 @@ void LLPanelMainInventory::selectAllItemsPanel()
mFilterTabs->selectFirstTab();
}
+bool LLPanelMainInventory::isRecentItemsPanelSelected()
+{
+ return (RECENT_ITEMS == getActivePanel()->getName());
+}
+
void LLPanelMainInventory::startSearch()
{
// this forces focus to line editor portion of search editor
@@ -439,7 +440,7 @@ void LLPanelMainInventory::setSortBy(const LLSD& userdata)
}
getActivePanel()->setSortOrder(sort_order_mask);
- if ("Recent Items" == getActivePanel()->getName())
+ if (isRecentItemsPanelSelected())
{
gSavedSettings.setU32("RecentItemsSortOrder", sort_order_mask);
}
@@ -801,8 +802,8 @@ void LLPanelMainInventory::toggleFindOptions()
void LLPanelMainInventory::setSelectCallback(const LLFolderView::signal_t::slot_type& cb)
{
- getChild<LLInventoryPanel>("All Items")->setSelectCallback(cb);
- getChild<LLInventoryPanel>("Recent Items")->setSelectCallback(cb);
+ getChild<LLInventoryPanel>(ALL_ITEMS)->setSelectCallback(cb);
+ getChild<LLInventoryPanel>(RECENT_ITEMS)->setSelectCallback(cb);
}
void LLPanelMainInventory::onSelectionChange(LLInventoryPanel *panel, const std::deque<LLFolderViewItem*>& items, BOOL user_action)
@@ -1200,11 +1201,11 @@ void LLPanelMainInventory::onAddButtonClick()
{
// Gray out the "New Folder" option when the Recent tab is active as new folders will not be displayed
// unless "Always show folders" is checked in the filter options.
- bool recent_active = ("Recent Items" == mActivePanel->getName());
+
LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
if (menu)
{
- menu->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active);
+ menu->getChild<LLMenuItemGL>("New Folder")->setEnabled(!isRecentItemsPanelSelected());
setUploadCostIfNeeded();
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index dfb8db9d12..257bce930c 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -81,6 +81,8 @@ public:
void selectAllItemsPanel();
const LLInventoryPanel* getActivePanel() const { return mActivePanel; }
+ bool isRecentItemsPanelSelected();
+
const std::string& getFilterText() const { return mFilterText; }
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 6bff95ab36..831c89b005 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -896,7 +896,7 @@ void LLPanelObject::getState( )
mSpinScaleY->setMaxValue(OBJECT_MAX_HOLE_SIZE_Y);
break;
default:
- if (editable)
+ if (editable && single_volume)
{
mSpinScaleX->set( 1.f - scale_x );
mSpinScaleY->set( 1.f - scale_y );
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 4762e15d8f..8294977f99 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -483,19 +483,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
mNoClassifieds = !mClassifiedsList->size();
}
- bool no_data = mNoPicks && mNoClassifieds;
- mNoItemsLabel->setVisible(no_data);
- if (no_data)
- {
- if(getAvatarId() == gAgentID)
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
- }
- else
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
- }
- }
+ updateNoItemsLabel();
}
LLPickItem* LLPanelPicks::getSelectedPickItem()
@@ -724,6 +712,13 @@ bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& resp
{
LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
mPicksList->removeItemByValue(pick_value);
+
+ mNoPicks = !mPicksList->size();
+ if (mNoPicks)
+ {
+ showAccordion("tab_picks", false);
+ }
+ updateNoItemsLabel();
}
updateButtons();
return false;
@@ -738,6 +733,13 @@ bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD
{
LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
mClassifiedsList->removeItemByValue(value);
+
+ mNoClassifieds = !mClassifiedsList->size();
+ if (mNoClassifieds)
+ {
+ showAccordion("tab_classifieds", false);
+ }
+ updateNoItemsLabel();
}
updateButtons();
return false;
@@ -851,6 +853,23 @@ void LLPanelPicks::updateButtons()
}
}
+void LLPanelPicks::updateNoItemsLabel()
+{
+ bool no_data = mNoPicks && mNoClassifieds;
+ mNoItemsLabel->setVisible(no_data);
+ if (no_data)
+ {
+ if (getAvatarId() == gAgentID)
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
+ }
+ }
+}
+
void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
{
mProfilePanel = profile_panel;
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 3bb7413ac3..fd7688b99d 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -87,6 +87,7 @@ public:
protected:
/*virtual*/void updateButtons();
+ void updateNoItemsLabel();
private:
void onClickDelete();
diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index b8aa976657..05fa2b58b1 100644
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
@@ -38,6 +38,7 @@
#include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
#include "llpanelsnapshot.h"
#include "llpostcard.h"
+#include "llregex.h"
#include "llsnapshotlivepreview.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewerwindow.h"
@@ -229,7 +230,7 @@ void LLPanelSnapshotPostcard::onSend()
boost::regex email_format("[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}(,[ \t]*[A-Za-z0-9.%+-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})*");
- if (to.empty() || !boost::regex_match(to, email_format))
+ if (to.empty() || !ll_regex_match(to, email_format))
{
LLNotificationsUtil::add("PromptRecipientEmail");
return;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 4c539ded38..f13910cde5 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -636,14 +636,17 @@ bool LLScriptEdCore::writeToFile(const std::string& filename)
void LLScriptEdCore::sync()
{
- // Sync with external editor.
- std::string tmp_file = mContainer->getTmpFileName();
- llstat s;
- if (LLFile::stat(tmp_file, &s) == 0) // file exists
- {
- if (mLiveFile) mLiveFile->ignoreNextUpdate();
- writeToFile(tmp_file);
- }
+ // Sync with external editor.
+ if (mLiveFile)
+ {
+ std::string tmp_file = mLiveFile->filename();
+ llstat s;
+ if (LLFile::stat(tmp_file, &s) == 0) // file exists
+ {
+ mLiveFile->ignoreNextUpdate();
+ writeToFile(tmp_file);
+ }
+ }
}
bool LLScriptEdCore::hasChanged()
@@ -1027,9 +1030,25 @@ void LLScriptEdCore::openInExternalEditor()
{
delete mLiveFile; // deletes file
- // Save the script to a temporary file.
- std::string filename = mContainer->getTmpFileName();
- writeToFile(filename);
+ // Generate a suitable filename
+ std::string script_name = mScriptName;
+ std::string forbidden_chars = "<>:\"\\/|?*";
+ for (std::string::iterator c = forbidden_chars.begin(); c != forbidden_chars.end(); c++)
+ {
+ script_name.erase(std::remove(script_name.begin(), script_name.end(), *c), script_name.end());
+ }
+ std::string filename = mContainer->getTmpFileName(script_name);
+
+ // Save the script to a temporary file.
+ if (!writeToFile(filename))
+ {
+ // In case some characters from script name are forbidden
+ // and not accounted for, name is too long or some other issue,
+ // try file that doesn't include script name
+ script_name.clear();
+ filename = mContainer->getTmpFileName(script_name);
+ writeToFile(filename);
+ }
// Start watching file changes.
mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1));
@@ -1419,7 +1438,7 @@ LLScriptEdContainer::LLScriptEdContainer(const LLSD& key) :
{
}
-std::string LLScriptEdContainer::getTmpFileName()
+std::string LLScriptEdContainer::getTmpFileName(const std::string& script_name)
{
// Take script inventory item id (within the object inventory)
// to consideration so that it's possible to edit multiple scripts
@@ -1431,7 +1450,14 @@ std::string LLScriptEdContainer::getTmpFileName()
LLMD5 script_id_hash((const U8 *)script_id.c_str());
script_id_hash.hex_digest(script_id_hash_str);
- return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl";
+ if (script_name.empty())
+ {
+ return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl";
+ }
+ else
+ {
+ return std::string(LLFile::tmpdir()) + "sl_script_" + script_name + "_" + script_id_hash_str + ".lsl";
+ }
}
bool LLScriptEdContainer::onExternalChange(const std::string& filename)
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 3cf22a0e6e..c1fea31063 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -205,7 +205,7 @@ public:
LLScriptEdContainer(const LLSD& key, const bool live);
protected:
- std::string getTmpFileName();
+ std::string getTmpFileName(const std::string& script_name);
bool onExternalChange(const std::string& filename);
virtual void saveIfNeeded(bool sync = true) = 0;
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index 14059f828a..3a7b06c55a 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -264,7 +264,9 @@ public:
virtual void validate(int validation_policy,
LLPointer<LLCertificateChain> cert_chain,
const LLSD& validation_params) =0;
-
+
+ // Clear cache if any
+ virtual void clearSertCache()=0;
};
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 737ef30ada..19db020a31 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -915,11 +915,19 @@ void _validateCert(int validation_policy,
}
if (validation_policy & VALIDATION_POLICY_SSL_KU)
{
+ // This stanza of code was changed 2021-06-09 as per details in SL-15370.
+ // Brief summary: a renewed certificate from Akamai only contains the
+ // 'Digital Signature' field and not the 'Key Encipherment' one. This code
+ // used to look for both and throw an exception at startup (ignored) and
+ // (for example) when buying L$ in the Viewer (fails with a UI message
+ // and an entry in the Viewer log). This modified code removes the second
+ // check for the 'Key Encipherment' field. If Akamai can provide a
+ // replacement certificate that has both fields, then this modified code
+ // will not be required.
if (current_cert_info.has(CERT_KEY_USAGE) && current_cert_info[CERT_KEY_USAGE].isArray() &&
- (!(_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],
- LLSD((std::string)CERT_KU_DIGITAL_SIGNATURE))) ||
!(_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],
- LLSD((std::string)CERT_KU_KEY_ENCIPHERMENT)))))
+ LLSD((std::string)CERT_KU_DIGITAL_SIGNATURE)))
+ )
{
LLTHROW(LLCertKeyUsageValidationException(current_cert_info));
}
diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h
index 0bc7f5230f..3bfac3f056 100644
--- a/indra/newview/llsechandler_basic.h
+++ b/indra/newview/llsechandler_basic.h
@@ -177,7 +177,10 @@ public:
virtual void validate(int validation_policy,
LLPointer<LLCertificateChain> ca_chain,
const LLSD& validation_params);
-
+
+ // Clears cache of certs validated agains store
+ virtual void clearSertCache() { mTrustedCertCache.clear(); }
+
protected:
std::vector<LLPointer<LLCertificate> > mCerts;
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 50884762a8..5bbdeb1f98 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1368,11 +1368,8 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
}
break;
case SELECT_TYPE_HUD:
- // use HUD-scaled grid
- mGridScale = LLVector3(0.25f, 0.25f, 0.25f);
- break;
case SELECT_TYPE_WORLD:
- mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
+ mGridScale = LLVector3(1.f, 1.f, 1.f) * llmin(gSavedSettings.getF32("GridResolution"), 0.5f);
break;
}
}
diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp
index f325315933..e02b21f036 100644
--- a/indra/newview/llskinningutil.cpp
+++ b/indra/newview/llskinningutil.cpp
@@ -131,7 +131,12 @@ void LLSkinningUtil::initSkinningMatrixPalette(
initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
for (U32 j = 0; j < count; ++j)
{
- LLJoint *joint = avatar->getJoint(skin->mJointNums[j]);
+ S32 joint_num = skin->mJointNums[j];
+ LLJoint *joint = NULL;
+ if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS)
+ {
+ joint = avatar->getJoint(joint_num);
+ }
llassert(joint);
if (joint)
{
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index c5d5be3509..f22be6481a 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1838,9 +1838,6 @@ bool idle_startup()
display_startup();
- //all categories loaded. lets create "My Favorites" category
- gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
-
// set up callbacks
LL_INFOS() << "Registering Callbacks" << LL_ENDL;
LLMessageSystem* msg = gMessageSystem;
@@ -2820,6 +2817,11 @@ void reset_login()
// Hide any other stuff
LLFloaterReg::hideVisibleInstances();
LLStartUp::setStartupState( STATE_BROWSER_INIT );
+
+ // Clear any verified certs and verify them again on next login
+ // to ensure cert matches server instead of just getting reused
+ LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
+ store->clearSertCache();
}
//---------------------------------------------------------------------------
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
index 93fa457bd0..7d4988c0cc 100644
--- a/indra/newview/llteleporthistorystorage.cpp
+++ b/indra/newview/llteleporthistorystorage.cpp
@@ -203,6 +203,12 @@ void LLTeleportHistoryStorage::load()
std::string line;
while (std::getline(file, line))
{
+ if (line.empty())
+ {
+ LL_WARNS() << "Teleport history contains empty line."<< LL_ENDL;
+ continue;
+ }
+
LLSD s_item;
std::istringstream iss(line);
if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index 3fcf193dec..fa2dd60ee0 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -405,7 +405,7 @@ void LLToolMgr::clearTransientTool()
void LLToolMgr::onAppFocusLost()
{
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
return;
if (mSelectedTool)
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 322d0bc727..c70fcedde5 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -460,8 +460,9 @@ BOOL LLToolPie::useClickAction(MASK mask,
&& object
&& !object->isAttachment()
&& LLPrimitive::isPrimitive(object->getPCode())
- && (object->getClickAction()
- || parent->getClickAction());
+ // useClickAction does not handle Touch (0) or Disabled action
+ && ((object->getClickAction() && object->getClickAction() != CLICK_ACTION_DISABLED)
+ || (parent && parent->getClickAction() && parent->getClickAction() != CLICK_ACTION_DISABLED));
}
@@ -472,18 +473,18 @@ U8 final_click_action(LLViewerObject* obj)
U8 click_action = CLICK_ACTION_TOUCH;
LLViewerObject* parent = obj->getRootEdit();
- if (obj->getClickAction()
- || (parent && parent->getClickAction()))
- {
- if (obj->getClickAction())
- {
- click_action = obj->getClickAction();
- }
- else if (parent && parent->getClickAction())
- {
- click_action = parent->getClickAction();
- }
- }
+ U8 object_action = obj->getClickAction();
+ U8 parent_action = parent ? parent->getClickAction() : CLICK_ACTION_TOUCH;
+ if (parent_action == CLICK_ACTION_DISABLED || object_action)
+ {
+ // CLICK_ACTION_DISABLED ("None" in UI) is intended for child action to
+ // override parent's action when assigned to parent or to child
+ click_action = object_action;
+ }
+ else if (parent_action)
+ {
+ click_action = parent_action;
+ }
return click_action;
}
@@ -657,9 +658,10 @@ bool LLToolPie::teleportToClickedLocation()
bool is_land = mHoverPick.mPickType == LLPickInfo::PICK_LAND;
bool pos_non_zero = !mHoverPick.mPosGlobal.isExactlyZero();
bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch());
- bool has_click_action = final_click_action(objp);
+ U8 click_action = final_click_action(objp); // default action: 0 - touch
+ bool has_click_action = (click_action || has_touch_handler) && click_action != CLICK_ACTION_DISABLED;
- if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action)))
+ if (pos_non_zero && (is_land || (is_in_world && !has_click_action)))
{
LLVector3d pos = mHoverPick.mPosGlobal;
pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot();
@@ -790,7 +792,8 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
}
else if ((!object || !object->isAttachment() || object->getClickAction() != CLICK_ACTION_DISABLED)
- && ((object && object->flagHandleTouch()) || (parent && parent->flagHandleTouch())))
+ && ((object && object->flagHandleTouch()) || (parent && parent->flagHandleTouch()))
+ && (!object || !object->isAvatar()))
{
show_highlight = true;
gViewerWindow->setCursor(UI_CURSOR_HAND);
@@ -1234,7 +1237,8 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
{
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE;
+ static LLCachedControl<bool> show_hover_tips(*LLUI::getInstance()->mSettingGroups["config"], "ShowHoverTips", true);
+ if (!show_hover_tips) return TRUE;
if (!mHoverPick.isValid()) return TRUE;
LLViewerObject* hover_object = mHoverPick.getObject();
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index fa3b44f702..a2c696c762 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -144,6 +144,7 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
httpOpts->setFollowRedirects(true);
+ httpOpts->setSSLVerifyPeer(false);
std::string url = this->getKeyVerificationURL(key);
if (url.empty())
@@ -185,6 +186,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+ httpOpts->setSSLVerifyPeer(false);
std::string url = this->getTranslateURL(fromTo.first, fromTo.second, msg);
if (url.empty())
@@ -195,6 +197,11 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts, httpHeaders);
+ if (LLApp::isQuitting())
+ {
+ return;
+ }
+
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@@ -205,7 +212,22 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
const LLSD::Binary &rawBody = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
std::string body(rawBody.begin(), rawBody.end());
- if (this->parseResponse(parseResult, body, translation, detected_lang, err_msg))
+ bool res = false;
+
+ try
+ {
+ res = this->parseResponse(parseResult, body, translation, detected_lang, err_msg);
+ }
+ catch (std::out_of_range&)
+ {
+ LL_WARNS() << "Out of range exception on string " << body << LL_ENDL;
+ }
+ catch (...)
+ {
+ LOG_UNHANDLED_EXCEPTION( "Exception on string " + body );
+ }
+
+ if (res)
{
// Fix up the response
LLStringUtil::replaceString(translation, "&lt;", "<");
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 4720a989b0..376a7fce76 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -28,9 +28,9 @@
#include "llviewerprecompiledheaders.h"
#include "llevents.h"
#include "lleventfilter.h"
+#include "llregex.h"
#include "llversioninfo.h"
#include "stringize.h"
-#include <boost/regex.hpp>
#if ! defined(LL_VIEWER_CHANNEL) \
|| ! defined(LL_VIEWER_VERSION_MAJOR) \
@@ -139,19 +139,19 @@ LLVersionInfo::ViewerMaturity LLVersionInfo::getViewerMaturity()
static const boost::regex is_project_channel("\\bProject\\b");
static const boost::regex is_release_channel("\\bRelease\\b");
- if (boost::regex_search(channel, is_release_channel))
+ if (ll_regex_search(channel, is_release_channel))
{
maturity = RELEASE_VIEWER;
}
- else if (boost::regex_search(channel, is_beta_channel))
+ else if (ll_regex_search(channel, is_beta_channel))
{
maturity = BETA_VIEWER;
}
- else if (boost::regex_search(channel, is_project_channel))
+ else if (ll_regex_search(channel, is_project_channel))
{
maturity = PROJECT_VIEWER;
}
- else if (boost::regex_search(channel, is_test_channel))
+ else if (ll_regex_search(channel, is_test_channel))
{
maturity = TEST_VIEWER;
}
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 7842d24279..c1b129750a 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -115,6 +115,7 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *
mCountSucceeded(0),
mTotalBytesFetched(0)
{
+ LLCoprocedureManager::instance().initializePool(VIEWER_ASSET_STORAGE_CORO_POOL);
}
@@ -128,6 +129,7 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *
mCountSucceeded(0),
mTotalBytesFetched(0)
{
+ LLCoprocedureManager::instance().initializePool(VIEWER_ASSET_STORAGE_CORO_POOL);
}
LLViewerAssetStorage::~LLViewerAssetStorage()
@@ -544,7 +546,7 @@ void LLViewerAssetStorage::assetRequestCoro(
LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts);
- if (LLApp::isQuitting() || !gAssetStorage)
+ if (LLApp::isExiting() || !gAssetStorage)
{
// Bail out if result arrives after shutdown has been started.
return;
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index bc07821ccd..0df6811f6a 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -793,7 +793,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
// Show the preview panel for textures and sounds to let
// user know that the image (or snapshot) arrived intact.
LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, serverInventoryItem, TRUE, TAKE_FOCUS_NO, (panel == NULL));
+ LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, serverInventoryItem, FALSE, TAKE_FOCUS_NO, (panel == NULL));
// restore keyboard focus
gFocusMgr.setKeyboardFocus(focus);
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index cb20801756..f97ba0930e 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -81,7 +81,7 @@ void LLViewerAudio::registerIdleListener()
}
}
-void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
+void LLViewerAudio::startInternetStreamWithAutoFade(const std::string &streamURI)
{
// Old and new stream are identical
if (mNextStreamURI == streamURI)
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index 16f9b63113..782285ce36 100644
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -55,7 +55,7 @@ public:
FADE_OUT,
};
- void startInternetStreamWithAutoFade(std::string streamURI);
+ void startInternetStreamWithAutoFade(const std::string &streamURI);
void stopInternetStreamWithAutoFade();
bool onIdleUpdate();
@@ -65,7 +65,8 @@ public:
F32 getFadeVolume();
bool getForcedTeleportFade() { return mForcedTeleportFade; };
void setForcedTeleportFade(bool fade) { mForcedTeleportFade = fade;} ;
- void setNextStreamURI(std::string stream) { mNextStreamURI = stream; } ;
+ std::string getNextStreamURI() { return mNextStreamURI; };
+ void setNextStreamURI(const std::string &stream) { mNextStreamURI = stream; } ;
void setWasPlaying(bool playing) { mWasPlaying = playing;} ;
private:
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 066c874eb8..109dc93261 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1499,10 +1499,9 @@ void render_ui_2d()
if (gSavedSettings.getBOOL("RenderUIBuffer"))
{
- LLUI* ui_inst = LLUI::getInstance();
- if (ui_inst->mDirty)
+ if (LLView::sIsRectDirty)
{
- ui_inst->mDirty = FALSE;
+ LLView::sIsRectDirty = false;
LLRect t_rect;
gPipeline.mUIScreen.bindTarget();
@@ -1510,25 +1509,25 @@ void render_ui_2d()
{
static const S32 pad = 8;
- ui_inst->mDirtyRect.mLeft -= pad;
- ui_inst->mDirtyRect.mRight += pad;
- ui_inst->mDirtyRect.mBottom -= pad;
- ui_inst->mDirtyRect.mTop += pad;
+ LLView::sDirtyRect.mLeft -= pad;
+ LLView::sDirtyRect.mRight += pad;
+ LLView::sDirtyRect.mBottom -= pad;
+ LLView::sDirtyRect.mTop += pad;
LLGLEnable scissor(GL_SCISSOR_TEST);
- static LLRect last_rect = ui_inst->mDirtyRect;
+ static LLRect last_rect = LLView::sDirtyRect;
//union with last rect to avoid mouse poop
- last_rect.unionWith(ui_inst->mDirtyRect);
+ last_rect.unionWith(LLView::sDirtyRect);
- t_rect = ui_inst->mDirtyRect;
- ui_inst->mDirtyRect = last_rect;
+ t_rect = LLView::sDirtyRect;
+ LLView::sDirtyRect = last_rect;
last_rect = t_rect;
-
- last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / ui_inst->getScaleFactor().mV[0]);
- last_rect.mRight = LLRect::tCoordType(last_rect.mRight / ui_inst->getScaleFactor().mV[0]);
- last_rect.mTop = LLRect::tCoordType(last_rect.mTop / ui_inst->getScaleFactor().mV[1]);
- last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / ui_inst->getScaleFactor().mV[1]);
+
+ last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]);
+ last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]);
+ last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]);
+ last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);
LLRect clip_rect(last_rect);
@@ -1540,7 +1539,7 @@ void render_ui_2d()
gPipeline.mUIScreen.flush();
gGL.setColorMask(true, false);
- ui_inst->mDirtyRect = t_rect;
+ LLView::sDirtyRect = t_rect;
}
LLGLDisable cull(GL_CULL_FACE);
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index afa84a5afc..f770db31dd 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -130,7 +130,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_FAVORITE, new ViewerFolderEntry("Favorites", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "Inv_SysOpen", "Inv_SysClosed", TRUE, false));
- addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "Inv_LookFolderOpen", "Inv_LookFolderClosed", TRUE, true));
+ addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "Inv_LookFolderOpen", "Inv_LookFolderClosed", TRUE, false));
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_SETTINGS, new ViewerFolderEntry("Settings", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 9ed2df2759..d35dbda907 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1237,6 +1237,7 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
httpOpts->setFollowRedirects(true);
httpOpts->setWantHeaders(true);
+ httpOpts->setSSLVerifyPeer(false); // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"
LLURL hostUrl(url.c_str());
std::string hostAuth = hostUrl.getAuthority();
@@ -1744,14 +1745,14 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" );
media_source->cookies_enabled( cookies_enabled || clean_browser);
- // collect 'plugins enabled' setting from prefs and send to embedded browser
- bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" );
- media_source->setPluginsEnabled( plugins_enabled || clean_browser);
-
// collect 'javascript enabled' setting from prefs and send to embedded browser
bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" );
media_source->setJavascriptEnabled( javascript_enabled || clean_browser);
+ // As of SL-15559 PDF files do not load in CEF v91 we enable plugins
+ // but explicitly disable Flash (PDF support in CEF is now treated as a plugin)
+ media_source->setPluginsEnabled(true);
+
bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index fbf057603e..5b1ad9e2a0 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -291,6 +291,8 @@ void force_error_bad_memory_access(void *);
void force_error_infinite_loop(void *);
void force_error_software_exception(void *);
void force_error_driver_crash(void *);
+void force_error_coroutine_crash(void *);
+void force_error_thread_crash(void *);
void handle_force_delete(void*);
void print_object_info(void*);
@@ -2361,6 +2363,24 @@ class LLAdvancedForceErrorDriverCrash : public view_listener_t
}
};
+class LLAdvancedForceErrorCoroutineCrash : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_coroutine_crash(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedForceErrorThreadCrash : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_thread_crash(NULL);
+ return true;
+ }
+};
+
class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -4135,25 +4155,31 @@ void near_sit_down_point(BOOL success, void *)
class LLLandSit : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gAgent.standUp();
- LLViewerParcelMgr::getInstance()->deselectLand();
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
- LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
-
- LLQuaternion target_rot;
- if (isAgentAvatarValid())
- {
- target_rot = gAgentAvatarp->getRotation();
- }
- else
- {
- target_rot = gAgent.getFrameAgent().getQuaternion();
- }
- gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f);
- return true;
- }
+ LLQuaternion target_rot;
+ if (isAgentAvatarValid())
+ {
+ target_rot = gAgentAvatarp->getRotation();
+ }
+ else
+ {
+ target_rot = gAgent.getFrameAgent().getQuaternion();
+ }
+ gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f);
+ return true;
+ }
+};
+
+class LLLandCanSit : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
+ return !posGlobal.isExactlyZero(); // valid position, not beyond draw distance
+ }
};
//-------------------------------------------------------------------
@@ -7254,7 +7280,7 @@ namespace
};
}
-void queue_actions(LLFloaterScriptQueue* q, const std::string& msg)
+bool queue_actions(LLFloaterScriptQueue* q, const std::string& msg)
{
QueueObjects func(q);
LLSelectMgr *mgr = LLSelectMgr::getInstance();
@@ -7276,6 +7302,7 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& msg)
{
LL_ERRS() << "Bad logic." << LL_ENDL;
}
+ q->closeFloater();
}
else
{
@@ -7284,6 +7311,7 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& msg)
LL_WARNS() << "Unexpected script compile failure." << LL_ENDL;
}
}
+ return !fail;
}
class LLToolsSelectedScriptAction : public view_listener_t
@@ -7331,8 +7359,10 @@ class LLToolsSelectedScriptAction : public view_listener_t
if (queue)
{
queue->setMono(mono);
- queue_actions(queue, msg);
- queue->setTitle(title);
+ if (queue_actions(queue, msg))
+ {
+ queue->setTitle(title);
+ }
}
else
{
@@ -8068,6 +8098,16 @@ void force_error_driver_crash(void *)
LLAppViewer::instance()->forceErrorDriverCrash();
}
+void force_error_coroutine_crash(void *)
+{
+ LLAppViewer::instance()->forceErrorCoroutineCrash();
+}
+
+void force_error_thread_crash(void *)
+{
+ LLAppViewer::instance()->forceErrorThreadCrash();
+}
+
class LLToolsUseSelectionForGrid : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -9240,6 +9280,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
+ view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
+ view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
// Advanced (toplevel)
@@ -9371,6 +9413,7 @@ void initialize_menus()
// Land pie menu
view_listener_t::addMenu(new LLLandBuild(), "Land.Build");
view_listener_t::addMenu(new LLLandSit(), "Land.Sit");
+ view_listener_t::addMenu(new LLLandCanSit(), "Land.CanSit");
view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");
view_listener_t::addMenu(new LLLandEdit(), "Land.Edit");
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 06172e366d..56370df751 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1888,7 +1888,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
if (parcel)
{
// Only update stream if parcel changed (recreated) or music is playing (enabled)
- if (!agent_parcel_update || gSavedSettings.getBOOL("MediaTentativeAutoPlay"))
+ static LLCachedControl<bool> already_playing(gSavedSettings, "MediaTentativeAutoPlay", true);
+ if (!agent_parcel_update || already_playing)
{
LLViewerParcelAskPlay::getInstance()->cancelNotification();
std::string music_url_raw = parcel->getMusicURL();
@@ -1906,7 +1907,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
LLViewerRegion *region = LLWorld::getInstance()->getRegion(msg->getSender());
if (region)
{
- optionally_start_music(music_url, parcel->mLocalID, region->getRegionID());
+ optionallyStartMusic(music_url, parcel->mLocalID, region->getRegionID(), !agent_parcel_update);
}
}
else
@@ -1943,9 +1944,13 @@ void LLViewerParcelMgr::onStartMusicResponse(const LLUUID &region_id, const S32
LL_INFOS("ParcelMgr") << "Starting parcel music " << url << LL_ENDL;
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(url);
}
+ else
+ {
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
+ }
}
-void LLViewerParcelMgr::optionally_start_music(const std::string &music_url, const S32 &local_id, const LLUUID &region_id)
+void LLViewerParcelMgr::optionallyStartMusic(const std::string &music_url, const S32 &local_id, const LLUUID &region_id, bool switched_parcel)
{
static LLCachedControl<bool> streaming_music(gSavedSettings, "AudioStreamingMusic", true);
if (streaming_music)
@@ -1955,25 +1960,35 @@ void LLViewerParcelMgr::optionally_start_music(const std::string &music_url, con
// only play music when you enter a new parcel if the UI control for this
// was not *explicitly* stopped by the user. (part of SL-4878)
LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();
+ LLViewerAudio* viewer_audio = LLViewerAudio::getInstance();
// ask mode //todo constants
if (autoplay_mode == 2)
{
- // stop previous stream
- LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
-
// if user set media to play - ask
if ((nearby_media_panel && nearby_media_panel->getParcelAudioAutoStart())
|| (!nearby_media_panel && tentative_autoplay))
{
- LLViewerParcelAskPlay::getInstance()->askToPlay(region_id,
- local_id,
- music_url,
- onStartMusicResponse);
+ // user did not stop audio
+ if (switched_parcel || music_url != viewer_audio->getNextStreamURI())
+ {
+ viewer_audio->startInternetStreamWithAutoFade(LLStringUtil::null);
+
+ LLViewerParcelAskPlay::getInstance()->askToPlay(region_id,
+ local_id,
+ music_url,
+ onStartMusicResponse);
+ }
+ // else do nothing:
+ // Parcel properties changed, but not url.
+ // We are already playing this url and asked about it when agent entered parcel
+ // or user started audio manually at some point
}
else
{
+ // stopped by the user, do not autoplay
LLViewerParcelAskPlay::getInstance()->cancelNotification();
+ viewer_audio->startInternetStreamWithAutoFade(LLStringUtil::null);
}
}
// autoplay
@@ -1985,11 +2000,12 @@ void LLViewerParcelMgr::optionally_start_music(const std::string &music_url, con
&& tentative_autoplay))
{
LL_INFOS("ParcelMgr") << "Starting parcel music " << music_url << LL_ENDL;
- LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url);
+ viewer_audio->startInternetStreamWithAutoFade(music_url);
}
- else
+ // autoplay off
+ else if(switched_parcel || music_url != viewer_audio->getNextStreamURI())
{
- LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
+ viewer_audio->startInternetStreamWithAutoFade(LLStringUtil::null);
}
}
}
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index 508a63c398..6ce389ab88 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -271,7 +271,7 @@ public:
//void makeLandmarkAtSelection();
static void onStartMusicResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play);
- static void optionally_start_music(const std::string &music_url, const S32 &local_id, const LLUUID &region_id);
+ static void optionallyStartMusic(const std::string &music_url, const S32 &local_id, const LLUUID &region_id, bool switched_parcel);
static void processParcelOverlay(LLMessageSystem *msg, void **user_data);
static void processParcelProperties(LLMessageSystem *msg, void **user_data);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 2fde4fe49c..ba02f92791 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -82,6 +82,8 @@
#include "llcallstack.h"
#include "llsettingsdaycycle.h"
+#include <boost/regex.hpp>
+
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
#endif
@@ -143,15 +145,22 @@ public:
// build a secondlife://{PLACE} SLurl from this SLapp
std::string url = "secondlife://";
+ boost::regex name_rx("[A-Za-z0-9()_%]+");
+ boost::regex coord_rx("[0-9]+");
for (int i = 0; i < num_params; i++)
{
if (i > 0)
{
url += "/";
}
+ if (!boost::regex_match(params[i].asString(), i > 0 ? coord_rx : name_rx))
+ {
+ return false;
+ }
+
url += params[i].asString();
}
-
+
// Process the SLapp as if it was a secondlife://{PLACE} SLurl
LLURLDispatcher::dispatch(url, "clicked", web, true);
return true;
@@ -178,7 +187,7 @@ public:
mLandp(NULL)
{}
- void buildCapabilityNames(LLSD& capabilityNames);
+ static void buildCapabilityNames(LLSD& capabilityNames);
// The surfaces and other layers
LLSurface* mLandp;
@@ -251,6 +260,12 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
// This loop is used for retrying a capabilities request.
do
{
+ if (STATE_WORLD_INIT > LLStartUp::getStartupState())
+ {
+ LL_INFOS("AppInit", "Capabilities") << "Aborting capabilities request, reason: returned to login screen" << LL_ENDL;
+ return;
+ }
+
regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
@@ -299,13 +314,19 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
regionp = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
- ++mSeedCapAttempts;
+ if (STATE_WORLD_INIT > LLStartUp::getStartupState())
+ {
+ LL_INFOS("AppInit", "Capabilities") << "Aborting capabilities request, reason: returned to login screen" << LL_ENDL;
+ return;
+ }
- if (LLApp::isExiting())
+ if (LLApp::isExiting() || gDisconnected)
{
return;
}
+ ++mSeedCapAttempts;
+
regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
@@ -420,7 +441,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
break; // no retry
}
- if (LLApp::isExiting())
+ if (LLApp::isExiting() || gDisconnected)
{
break;
}
@@ -528,7 +549,7 @@ void LLViewerRegionImpl::requestSimulatorFeatureCoro(std::string url, U64 region
continue;
}
- if (LLApp::isExiting())
+ if (LLApp::isExiting() || gDisconnected)
{
break;
}
@@ -2241,7 +2262,7 @@ void LLViewerRegion::setSimulatorFeaturesReceived(bool received)
mSimulatorFeaturesReceived = received;
if (received)
{
- mSimulatorFeaturesReceivedSignal(getRegionID());
+ mSimulatorFeaturesReceivedSignal(getRegionID(), this);
mSimulatorFeaturesReceivedSignal.disconnect_all_slots();
}
}
@@ -2916,6 +2937,7 @@ void LLViewerRegion::unpackRegionHandshake()
mRegionTimer.reset(); //reset region timer.
}
+// static
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
{
capabilityNames.append("AbuseCategories");
@@ -3183,7 +3205,7 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
// so that they can safely use getCapability().
if (received)
{
- mCapabilitiesReceivedSignal(getRegionID());
+ mCapabilitiesReceivedSignal(getRegionID(), this);
LLFloaterPermsDefault::sendInitialPerms();
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index dfd8c64f76..fcbf56c81f 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -94,7 +94,7 @@ public:
NUM_PARTITIONS
} eObjectPartitions;
- typedef boost::signals2::signal<void(const LLUUID& region_id)> caps_received_signal_t;
+ typedef boost::signals2::signal<void(const LLUUID& region_id, LLViewerRegion* regionp)> caps_received_signal_t;
LLViewerRegion(const U64 &handle,
const LLHost &host,
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 21985d5a8a..1d13a306ef 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1928,7 +1928,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
if (!LLAppViewer::instance()->restoreErrorTrap())
{
- LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL;
+ // this always happens, so downgrading it to INFO
+ LL_INFOS("Window") << " Someone took over my signal/exception handler (post createWindow; normal)" << LL_ENDL;
}
const bool do_not_enforce = false;
@@ -2700,7 +2701,7 @@ void LLViewerWindow::draw()
if (!gSavedSettings.getBOOL("RenderUIBuffer"))
{
- LLUI::getInstance()->mDirtyRect = getWindowRectScaled();
+ LLView::sDirtyRect = getWindowRectScaled();
}
// HACK for timecode debugging
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f69b9b3861..e085a945a8 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -10584,7 +10584,8 @@ void LLVOAvatar::accountRenderComplexityForObject(
LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
<< " total: " << attachment_total_cost
<< ", volume: " << attachment_volume_cost
- << ", textures: " << attachment_texture_cost
+ << ", " << textures.size()
+ << " textures: " << attachment_texture_cost
<< ", " << volume->numChildren()
<< " children: " << attachment_children_cost
<< LL_ENDL;
@@ -10684,10 +10685,23 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
ETextureIndex tex_index = baked_dict->mTextureIndex;
if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
{
- if (isTextureVisible(tex_index))
- {
- cost +=COMPLEXITY_BODY_PART_COST;
- }
+ // Same as isTextureVisible(), but doesn't account for isSelf to ensure identical numbers for all avatars
+ if (isIndexLocalTexture(tex_index))
+ {
+ if (isTextureDefined(tex_index, 0))
+ {
+ cost += COMPLEXITY_BODY_PART_COST;
+ }
+ }
+ else
+ {
+ // baked textures can use TE images directly
+ if (isTextureDefined(tex_index)
+ && (getTEImage(tex_index)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha))
+ {
+ cost += COMPLEXITY_BODY_PART_COST;
+ }
+ }
}
}
LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL;
@@ -10728,8 +10742,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
// Diagnostic output to identify all avatar-related textures.
// Does not affect rendering cost calculation.
- // Could be wrapped in a debug option if output becomes problematic.
- if (isSelf())
+ if (isSelf() && debugLoggingEnabled("ARCdetail"))
{
// print any attachment textures we didn't already know about.
for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 689eeee0e3..5ebc65405f 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -44,6 +44,9 @@ F32 LLVOCacheEntry::sFrontPixelThreshold = 1.0f;
F32 LLVOCacheEntry::sRearPixelThreshold = 1.0f;
BOOL LLVOCachePartition::sNeedsOcclusionCheck = FALSE;
+const S32 ENTRY_HEADER_SIZE = 6 * sizeof(S32);
+const S32 MAX_ENTRY_BODY_SIZE = 10000;
+
BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
{
return apr_file->read(src, n_bytes) == n_bytes ;
@@ -111,32 +114,22 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
{
S32 size = -1;
BOOL success;
+ static U8 data_buffer[ENTRY_HEADER_SIZE];
mDP.assignBuffer(mBuffer, 0);
-
- success = check_read(apr_file, &mLocalID, sizeof(U32));
- if(success)
- {
- success = check_read(apr_file, &mCRC, sizeof(U32));
- }
- if(success)
- {
- success = check_read(apr_file, &mHitCount, sizeof(S32));
- }
- if(success)
- {
- success = check_read(apr_file, &mDupeCount, sizeof(S32));
- }
- if(success)
- {
- success = check_read(apr_file, &mCRCChangeCount, sizeof(S32));
- }
- if(success)
- {
- success = check_read(apr_file, &size, sizeof(S32));
+
+ success = check_read(apr_file, (void *)data_buffer, ENTRY_HEADER_SIZE);
+ if (success)
+ {
+ memcpy(&mLocalID, data_buffer, sizeof(U32));
+ memcpy(&mCRC, data_buffer + sizeof(U32), sizeof(U32));
+ memcpy(&mHitCount, data_buffer + (2 * sizeof(U32)), sizeof(S32));
+ memcpy(&mDupeCount, data_buffer + (3 * sizeof(U32)), sizeof(S32));
+ memcpy(&mCRCChangeCount, data_buffer + (4 * sizeof(U32)), sizeof(S32));
+ memcpy(&size, data_buffer + (5 * sizeof(U32)), sizeof(S32));
// Corruption in the cache entries
- if ((size > 10000) || (size < 1))
+ if ((size > MAX_ENTRY_BODY_SIZE) || (size < 1))
{
// We've got a bogus size, skip reading it.
// We won't bother seeking, because the rest of this file
@@ -345,26 +338,25 @@ void LLVOCacheEntry::dump() const
<< LL_ENDL;
}
-BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
+S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const
{
- static const S32 data_buffer_size = 6 * sizeof(S32);
- static U8 data_buffer[data_buffer_size];
S32 size = mDP.getBufferSize();
+ if (size > MAX_ENTRY_BODY_SIZE)
+ {
+ LL_WARNS() << "Failed to write entry with size above allowed limit: " << size << LL_ENDL;
+ return 0;
+ }
+
memcpy(data_buffer, &mLocalID, sizeof(U32));
memcpy(data_buffer + sizeof(U32), &mCRC, sizeof(U32));
memcpy(data_buffer + (2 * sizeof(U32)), &mHitCount, sizeof(S32));
memcpy(data_buffer + (3 * sizeof(U32)), &mDupeCount, sizeof(S32));
memcpy(data_buffer + (4 * sizeof(U32)), &mCRCChangeCount, sizeof(S32));
memcpy(data_buffer + (5 * sizeof(U32)), &size, sizeof(S32));
+ memcpy(data_buffer + ENTRY_HEADER_SIZE, (void*)mBuffer, size);
- BOOL success = check_write(apr_file, (void*)data_buffer, data_buffer_size);
- if (success)
- {
- success = check_write(apr_file, (void*)mBuffer, size);
- }
-
- return success;
+ return ENTRY_HEADER_SIZE + size;
}
//static
@@ -1393,11 +1385,11 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
bool success = true ;
{
std::string filename;
+ LLUUID cache_id;
getObjectCacheFilename(handle, filename);
LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
- LLUUID cache_id ;
- success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ;
+ success = check_read(&apr_file, cache_id.mData, UUID_BYTES);
if(success)
{
@@ -1409,7 +1401,7 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
if(success)
{
- S32 num_entries;
+ S32 num_entries; // if removal was enabled during write num_entries might be wrong
success = check_read(&apr_file, &num_entries, sizeof(S32)) ;
if(success)
@@ -1516,28 +1508,57 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
{
std::string filename;
getObjectCacheFilename(handle, filename);
- LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+ LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY|APR_TRUNCATE, mLocalAPRFilePoolp);
- success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ;
-
+ success = check_write(&apr_file, (void*)id.mData, UUID_BYTES);
if(success)
{
- S32 num_entries = cache_entry_map.size() ;
+ S32 num_entries = cache_entry_map.size(); // if removal is enabled num_entries might be wrong
success = check_write(&apr_file, &num_entries, sizeof(S32));
-
- // This can have a lot of entries, so might be better to dump them into buffer first and write in one go.
- for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
- {
- if(!removal_enabled || iter->second->isValid())
- {
- success = iter->second->writeToFile(&apr_file) ;
- if(!success)
- {
- break;
- }
- }
- }
+ if (success)
+ {
+ const S32 buffer_size = 32768; //should be large enough for couple MAX_ENTRY_BODY_SIZE
+ U8 data_buffer[buffer_size]; // generaly entries are fairly small, so collect them and drop onto disk in one go
+ S32 size_in_buffer = 0;
+
+ // This can have a lot of entries, so might be better to dump them into buffer first and write in one go.
+ for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
+ {
+ if (!removal_enabled || iter->second->isValid())
+ {
+ S32 size = iter->second->writeToBuffer(data_buffer + size_in_buffer);
+
+ if (size > ENTRY_HEADER_SIZE) // body is minimum of 1
+ {
+ size_in_buffer += size;
+ }
+ else
+ {
+ success = false;
+ break;
+ }
+
+ // Make sure we have space in buffer for next element
+ if (buffer_size - size_in_buffer < MAX_ENTRY_BODY_SIZE + ENTRY_HEADER_SIZE)
+ {
+ success = check_write(&apr_file, (void*)data_buffer, size_in_buffer);
+ size_in_buffer = 0;
+ if (!success)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if (success && size_in_buffer > 0)
+ {
+ // final write
+ success = check_write(&apr_file, (void*)data_buffer, size_in_buffer);
+ size_in_buffer = 0;
+ }
+ }
}
}
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 6c95541c11..dd6afd6b85 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -106,7 +106,7 @@ public:
F32 getSceneContribution() const { return mSceneContrib;}
void dump() const;
- BOOL writeToFile(LLAPRFile* apr_file) const;
+ S32 writeToBuffer(U8 *data_buffer) const;
LLDataPackerBinaryBuffer *getDP();
void recordHit();
void recordDupe() { mDupeCount++; }
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 7d8aa6fbbd..4d2eac8c09 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -652,7 +652,6 @@ void LLVivoxVoiceClient::idle(void* user_data)
{
}
-
//=========================================================================
// the following are methods to support the coroutine implementation of the
// voice connection and processing. They should only be called in the context
@@ -699,12 +698,15 @@ void LLVivoxVoiceClient::voiceControlCoro()
gSavedSettings.getControl("VivoxVadNoiseFloor")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
gSavedSettings.getControl("VivoxVadSensitivity")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
- if (mTuningMode)
+ if (mTuningMode && !sShuttingDown)
{
performMicTuning();
}
- waitForChannel(); // this doesn't normally return unless relog is needed or shutting down
+ if (!sShuttingDown)
+ {
+ waitForChannel(); // this doesn't normally return unless relog is needed or shutting down
+ }
LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL;
endAndDisconnectSession();
@@ -746,7 +748,6 @@ void LLVivoxVoiceClient::voiceControlCoro()
LL_INFOS("Voice") << "exiting" << LL_ENDL;
}
-
bool LLVivoxVoiceClient::startAndConnectSession()
{
bool ok = false;
@@ -1047,7 +1048,14 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
{
F32 timeout = pow(PROVISION_RETRY_TIMEOUT, static_cast<float>(retryCount));
LL_WARNS("Voice") << "Provision CAP 404. Retrying in " << timeout << " seconds." << LL_ENDL;
- llcoro::suspendUntilTimeout(timeout);
+ if (sShuttingDown)
+ {
+ return false;
+ }
+ else
+ {
+ llcoro::suspendUntilTimeout(timeout);
+ }
}
else if (!status)
{
@@ -1274,8 +1282,13 @@ bool LLVivoxVoiceClient::loginToVivox()
// tell the user there is a problem
LL_WARNS("Voice") << "login " << loginresp << " will retry login in " << timeout << " seconds." << LL_ENDL;
-
- llcoro::suspendUntilTimeout(timeout);
+
+ if (!sShuttingDown)
+ {
+ // Todo: this is way to long, viewer can get stuck waiting during shutdown
+ // either make it listen to pump or split in smaller waits with checks for shutdown
+ llcoro::suspendUntilTimeout(timeout);
+ }
}
else if (loginresp == "failed")
{
@@ -1341,6 +1354,11 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+ if (sShuttingDown)
+ {
+ break;
+ }
+
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
// Don't get confused by prior queued events -- note that it's
// very important that mVivoxPump is an LLEventMailDrop, which
@@ -1580,6 +1598,12 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
{
result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, SESSION_JOIN_TIMEOUT, timeoutResult);
+ if (sShuttingDown)
+ {
+ mIsJoiningSession = false;
+ return false;
+ }
+
LL_INFOS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
{
@@ -1774,7 +1798,7 @@ bool LLVivoxVoiceClient::waitForChannel()
if (sShuttingDown)
{
- logoutOfVivox(true);
+ logoutOfVivox(false);
return false;
}
@@ -1818,7 +1842,7 @@ bool LLVivoxVoiceClient::waitForChannel()
// the parcel is changed, or we have no pending audio sessions,
// so try to request the parcel voice info
// if we have the cap, we move to the appropriate state
- requestParcelVoiceInfo();
+ requestParcelVoiceInfo(); //suspends for http reply
}
else if (sessionNeedsRelog(mNextAudioSession))
{
@@ -1830,7 +1854,7 @@ bool LLVivoxVoiceClient::waitForChannel()
{
sessionStatePtr_t joinSession = mNextAudioSession;
mNextAudioSession.reset();
- if (!runSession(joinSession))
+ if (!runSession(joinSession)) //suspends
{
LL_DEBUGS("Voice") << "runSession returned false; leaving inner loop" << LL_ENDL;
break;
@@ -1845,7 +1869,7 @@ bool LLVivoxVoiceClient::waitForChannel()
}
}
- if (!mNextAudioSession)
+ if (!mNextAudioSession && !sShuttingDown)
{
llcoro::suspendUntilTimeout(1.0);
}
@@ -1866,9 +1890,9 @@ bool LLVivoxVoiceClient::waitForChannel()
mIsProcessingChannels = false;
- logoutOfVivox(true);
+ logoutOfVivox(!sShuttingDown /*bool wait*/);
- if (mRelogRequested)
+ if (mRelogRequested && !sShuttingDown)
{
LL_DEBUGS("Voice") << "Relog Requested, restarting provisioning" << LL_ENDL;
if (!provisionVoiceAccount())
@@ -1918,7 +1942,12 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
while (mVoiceEnabled && isGatewayRunning() && !mSessionTerminateRequested && !mTuningMode)
{
- sendCaptureAndRenderDevices();
+ sendCaptureAndRenderDevices(); // suspends
+ if (mSessionTerminateRequested)
+ {
+ break;
+ }
+
if (mAudioSession && mAudioSession->mParticipantsChanged)
{
mAudioSession->mParticipantsChanged = false;
@@ -2145,7 +2174,7 @@ bool LLVivoxVoiceClient::performMicTuning()
mIsInTuningMode = true;
llcoro::suspend();
- while (mTuningMode)
+ while (mTuningMode && !sShuttingDown)
{
if (mCaptureDeviceDirty || mRenderDeviceDirty)
@@ -2181,9 +2210,12 @@ bool LLVivoxVoiceClient::performMicTuning()
tuningCaptureStartSendMessage(1); // 1-loop, zero, don't loop
//---------------------------------------------------------------------
- llcoro::suspend();
+ if (!sShuttingDown)
+ {
+ llcoro::suspend();
+ }
- while (mTuningMode && !mCaptureDeviceDirty && !mRenderDeviceDirty)
+ while (mTuningMode && !mCaptureDeviceDirty && !mRenderDeviceDirty && !sShuttingDown)
{
// process mic/speaker volume changes
if (mTuningMicVolumeDirty || mTuningSpeakerVolumeDirty)
@@ -2223,7 +2255,7 @@ bool LLVivoxVoiceClient::performMicTuning()
// transition out of mic tuning
tuningCaptureStopSendMessage();
- if (mCaptureDeviceDirty || mRenderDeviceDirty)
+ if ((mCaptureDeviceDirty || mRenderDeviceDirty) && !sShuttingDown)
{
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
}
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 746201af04..75ff5429f3 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -446,7 +446,6 @@ protected:
// local audio updates, mic mute, speaker mute, mic volume and speaker volumes
void sendLocalAudioUpdates();
-
/////////////////////////////
// Response/Event handlers
void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle, std::string &versionID);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 3bdb8a2981..ca5305b169 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -377,6 +377,18 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
{
delete mTextureAnimp;
mTextureAnimp = NULL;
+
+ for (S32 i = 0; i < getNumTEs(); i++)
+ {
+ LLFace* facep = mDrawable->getFace(i);
+ if (facep && facep->mTextureMatrix)
+ {
+ // delete or reset
+ delete facep->mTextureMatrix;
+ facep->mTextureMatrix = NULL;
+ }
+ }
+
gPipeline.markTextured(mDrawable);
mFaceMappingChanged = TRUE;
mTexAnimMode = 0;
@@ -476,6 +488,18 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
{
delete mTextureAnimp;
mTextureAnimp = NULL;
+
+ for (S32 i = 0; i < getNumTEs(); i++)
+ {
+ LLFace* facep = mDrawable->getFace(i);
+ if (facep && facep->mTextureMatrix)
+ {
+ // delete or reset
+ delete facep->mTextureMatrix;
+ facep->mTextureMatrix = NULL;
+ }
+ }
+
gPipeline.markTextured(mDrawable);
mFaceMappingChanged = TRUE;
mTexAnimMode = 0;
@@ -3987,7 +4011,25 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
{
if (textures.find(img->getID()) == textures.end())
{
- S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ S32 texture_cost = 0;
+ S8 type = img->getType();
+ if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
+ {
+ const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img);
+ if (fetched_texturep
+ && fetched_texturep->getFTType() == FTT_LOCAL_FILE
+ && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD)
+ )
+ {
+ // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256).
+ // Hardcode cost from larger one to not cause random complexity changes
+ texture_cost = 320;
+ }
+ }
+ if (texture_cost == 0)
+ {
+ texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ }
textures.insert(texture_cost_t::value_type(img->getID(), texture_cost));
}
}
@@ -5450,8 +5492,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 useage = group->getSpatialPartition()->mBufferUsage;
- LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
- LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
+ static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
@@ -6217,7 +6259,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
#endif
//calculate maximum number of vertices to store in a single buffer
- LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 52b3c33512..a3036ff6d0 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -31,15 +31,6 @@
const U32 WATCHDOG_SLEEP_TIME_USEC = 1000000;
-void default_killer_callback()
-{
-#ifdef LL_WINDOWS
- RaiseException(0,0,0,0);
-#else
- raise(SIGQUIT);
-#endif
-}
-
// This class runs the watchdog timing thread.
class LLWatchdogTimerThread : public LLThread
{
@@ -158,11 +149,10 @@ void LLWatchdogTimeout::ping(const std::string& state)
}
// LLWatchdog
-LLWatchdog::LLWatchdog() :
- mSuspectsAccessMutex(),
- mTimer(NULL),
- mLastClockCount(0),
- mKillerCallback(&default_killer_callback)
+LLWatchdog::LLWatchdog()
+ :mSuspectsAccessMutex()
+ ,mTimer(NULL)
+ ,mLastClockCount(0)
{
}
@@ -184,9 +174,8 @@ void LLWatchdog::remove(LLWatchdogEntry* e)
unlockThread();
}
-void LLWatchdog::init(killer_event_callback func)
+void LLWatchdog::init()
{
- mKillerCallback = func;
if(!mSuspectsAccessMutex && !mTimer)
{
mSuspectsAccessMutex = new LLMutex();
@@ -253,8 +242,7 @@ void LLWatchdog::run()
mTimer->stop();
}
- LL_INFOS() << "Watchdog detected error:" << LL_ENDL;
- mKillerCallback();
+ LL_ERRS() << "Watchdog timer expired; assuming viewer is hung and crashing" << LL_ENDL;
}
}
diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h
index 9a6624258e..ce5cf748f4 100644
--- a/indra/newview/llwatchdog.h
+++ b/indra/newview/llwatchdog.h
@@ -83,9 +83,7 @@ public:
void add(LLWatchdogEntry* e);
void remove(LLWatchdogEntry* e);
- typedef boost::function<void (void)> killer_event_callback;
-
- void init(killer_event_callback func = NULL);
+ void init();
void run();
void cleanup();
@@ -98,8 +96,6 @@ private:
LLMutex* mSuspectsAccessMutex;
LLWatchdogTimerThread* mTimer;
U64 mLastClockCount;
-
- killer_event_callback mKillerCallback;
};
#endif // LL_LLTHREADWATCHDOG_H
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index 63257d6543..b8f1ec35f6 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -38,6 +38,7 @@
#include "llfloaterreg.h"
#include "lllogininstance.h"
#include "llparcel.h"
+#include "llregex.h"
#include "llsd.h"
#include "llui.h"
#include "lluri.h"
@@ -51,8 +52,6 @@
#include "lluriparser.h"
#include "uriparser/Uri.h"
-#include <boost/regex.hpp>
-
bool on_load_url_external_response(const LLSD& notification, const LLSD& response, bool async );
@@ -237,15 +236,15 @@ bool LLWeb::useExternalBrowser(const std::string &url)
up.extractParts();
std::string uri_string = up.host();
- boost::regex pattern = boost::regex("\\b(lindenlab.com|secondlife.com)$", boost::regex::perl|boost::regex::icase);
+ boost::regex pattern = boost::regex("\\b(lindenlab.com|secondlife.com|secondlife.io)$", boost::regex::perl|boost::regex::icase);
boost::match_results<std::string::const_iterator> matches;
- return !(boost::regex_search(uri_string, matches, pattern));
+ return !(ll_regex_search(uri_string, matches, pattern));
}
else
{
boost::regex pattern = boost::regex("^mailto:", boost::regex::perl | boost::regex::icase);
boost::match_results<std::string::const_iterator> matches;
- return boost::regex_search(url, matches, pattern);
+ return ll_regex_search(url, matches, pattern);
}
#endif
}
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index 569f479a16..ff899fe895 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -113,6 +113,7 @@ void LLWebProfile::uploadImageCoro(LLPointer<LLImageFormatted> image, std::strin
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
+ httpOpts->setSSLVerifyPeer(false); ; // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"
// Get upload configuration data.
std::string configUrl(getProfileURL(std::string()) + "snapshots/s3_upload_config");
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index 730aa3774f..d55e1b7cd3 100644
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -51,7 +51,7 @@ bool LLEnvironmentRequest::initiate(LLEnvironment::environment_apply_fn cb)
if (!cur_region->capabilitiesReceived())
{
LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL;
- cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID &region_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
+ cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID &region_id, LLViewerRegion* regionp) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
return false;
}
diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
index dcedaceaeb..bba30626b2 100644
--- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml
+++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
@@ -49,7 +49,7 @@
layout="topleft"
name="folder_label"
top_pad="10"
- value="Landmark location:"
+ value="Save this landmark in:"
width="290" />
<combo_box
follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 3cc99b28c9..7786ba8a1c 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -626,23 +626,6 @@
top_delta="16"
width="300" />
- <!-- SL-12594, basic shaders always enabled, no fixed-function GL
- <check_box
- control_name="VertexShaderEnable"
- height="16"
- initial_value="true"
- label="Basic shaders"
- layout="topleft"
- left="420"
- name="BasicShaders"
- tool_tip="Disabling this option may prevent some graphics card drivers from crashing"
- top_delta="16"
- width="300">
- <check_box.commit_callback
- function="Pref.VertexShaderEnable" />
- </check_box>
- -->
-
<slider
control_name="RenderTerrainDetail"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/floater_url_entry.xml b/indra/newview/skins/default/xui/en/floater_url_entry.xml
index 29fb29fabf..2dfc0fd125 100644
--- a/indra/newview/skins/default/xui/en/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/en/floater_url_entry.xml
@@ -66,7 +66,7 @@
layout="topleft"
left="152"
name="loading_label"
- visible="true">
+ visible="false">
Loading...
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index eda9739976..5a35bbf121 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -152,6 +152,14 @@
parameter="category" />
</menu_item_call>
<menu_item_call
+ label="New Outfit"
+ layout="topleft"
+ name="New Outfit">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="outfit" />
+ </menu_item_call>
+ <menu_item_call
label="New Script"
layout="topleft"
name="New Script">
diff --git a/indra/newview/skins/default/xui/en/menu_land.xml b/indra/newview/skins/default/xui/en/menu_land.xml
index 2ad5cbbe95..1ce0d65b3e 100644
--- a/indra/newview/skins/default/xui/en/menu_land.xml
+++ b/indra/newview/skins/default/xui/en/menu_land.xml
@@ -18,6 +18,8 @@
<menu_item_call
label="Sit Here"
name="Sit Here">
+ <menu_item_call.on_enable
+ function="Land.CanSit" />
<menu_item_call.on_click
function="Land.Sit" />
</menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index c550f69d26..72cce2208f 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2657,6 +2657,18 @@ function="World.EnvPreset"
function="Advanced.ForceErrorSoftwareException" />
</menu_item_call>
<menu_item_call
+ label="Force a Crash in a Coroutine"
+ name="Force a Crash in a Coroutine">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorCoroutineCrash" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force a Crash in a Thread"
+ name="Force a Crash in a Thread">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorThreadCrash" />
+ </menu_item_call>
+ <menu_item_call
label="Force Disconnect Viewer"
name="Force Disconnect Viewer">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 4a02b576c2..d4f71fb370 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -10055,6 +10055,15 @@ Removal of the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; from the simulat
Cannot save your selection because you do not have permission to modify the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoTransNoSaveToContents"
+ type="notify">
+ <tag>fail</tag>
+ Cannot save &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; to object contents because you do not have permission to transfer the object's ownership.
+ </notification>
+
<notification
icon="alertmodal.tga"
name="NoCopyNoSaveSelection"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index 726e713595..5568ccb792 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -234,32 +234,6 @@
left_pad="32"
name="image_right"
top="0" />
- <text
- follows="left|top"
- font="SansSerifLarge"
- text_color="White"
- height="64"
- name="image_caption_left"
- left="0"
- halign="center"
- top="408"
- word_wrap="true"
- width="400">
- Your first step is Learning Island. Find the exit portal!
- </text>
- <text
- follows="left|top"
- font="SansSerifLarge"
- text_color="White"
- height="64"
- name="image_caption_right"
- left="432"
- halign="center"
- top="408"
- word_wrap="true"
- width="400">
- Then explore Social Island and meet other new residents!
- </text>
</layout_panel>
<layout_panel
height="100"
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 2dae2649a9..1c9aa1eb83 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -151,7 +151,7 @@
layout="topleft"
auto_resize="true"
user_resize="true"
- min_width="254"
+ min_width="342"
name="favorites_layout_panel"
width="342">
<icon
@@ -198,8 +198,8 @@
tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
top="13"
valign="bottom"
- width="205">
- Your saved locations will appear here.
+ width="290">
+ Places you save to your favorites bar will appear here.
</label>
<!-- More button actually is a text box. -->
<more_button
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 6732f4ff1c..dff6f6e600 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -148,20 +148,6 @@
</radio_group>
<check_box
- top_delta="2"
- enabled="true"
- follows="left|top"
- height="18"
- initial_value="true"
- control_name="BrowserPluginsEnabled"
- label="Enable plugins"
- left_delta="20"
- mouse_opaque="true"
- name="browser_plugins_enabled"
- radio_style="false"
- width="400"
- top_pad="5"/>
- <check_box
top_delta="4"
enabled="true"
follows="left|top"
@@ -241,24 +227,23 @@
height="10"
layout="topleft"
left="30"
- name="Proxy Settings:"
+ name="Proxy Settings 1"
+ mouse_opaque="false"
+ top_pad="10"
+ width="300">
+ Proxy Settings:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="80"
+ name="Proxy Settings 2"
mouse_opaque="false"
top_pad="5"
width="300">
- Proxy Settings:
+ Your system's existing proxy settings will be used
</text>
- <button
- label="Adjust proxy settings"
- follows="left|top"
- height="23"
- width="140"
- label_selected="Browse"
- layout="topleft"
- left_delta="50"
- name="set_proxy"
- top_pad="5"
- >
- <button.commit_callback
- function="Pref.Proxy" />
- </button>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index ada980cda1..9023d68ea9 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -35,7 +35,7 @@
</panel.string>
<panel
height="18"
- left="-458"
+ left="-398"
top="0"
width="120"
follows="right|top"
@@ -75,7 +75,7 @@
</panel>
<panel
height="18"
- left="-458"
+ left="-398"
width="185"
top="1"
follows="right|top"
@@ -142,7 +142,7 @@
left_pad="0"
name="TimeText"
tool_tip="Current time (Pacific)"
- width="145">
+ width="85">
24:00 AM PST
</text>
<icon
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f604a16b0b..d115e09d5b 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2298,7 +2298,7 @@ For AI Character: Get the closest navigable point to the point provided.
<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string>
<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
<string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string>
- <string name="FavoritesNoMatchingItems">To add a place to your favorites bar, click the star to the right of the location name.</string>
+ <string name="FavoritesNoMatchingItems">To add a place to your favorites, click the star to the right of the location name, then save the landmark to "Favorites bar".</string>
<string name="MarketplaceNoListing">You have no listings yet.</string>
<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>
<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
diff --git a/indra/newview/tests/cppfeatures_test.cpp b/indra/newview/tests/cppfeatures_test.cpp
new file mode 100644
index 0000000000..923bb1e1b2
--- /dev/null
+++ b/indra/newview/tests/cppfeatures_test.cpp
@@ -0,0 +1,386 @@
+/**
+ * @file cppfeatures_test
+ * @author Vir
+ * @date 2021-03
+ * @brief cpp features
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// Tests related to newer C++ features, for verifying support across compilers and platforms
+
+#include "linden_common.h"
+#include "../test/lltut.h"
+
+namespace tut
+{
+
+struct cpp_features_test {};
+typedef test_group<cpp_features_test> cpp_features_test_t;
+typedef cpp_features_test_t::object cpp_features_test_object_t;
+tut::cpp_features_test_t tut_cpp_features_test("LLCPPFeatures");
+
+// bracket initializers
+// Can initialize containers or values using curly brackets
+template<> template<>
+void cpp_features_test_object_t::test<1>()
+{
+ S32 explicit_val{3};
+ ensure(explicit_val==3);
+
+ S32 default_val{};
+ ensure(default_val==0);
+
+ std::vector<S32> fibs{1,1,2,3,5};
+ ensure(fibs[4]==5);
+}
+
+// auto
+//
+// https://en.cppreference.com/w/cpp/language/auto
+//
+// Can use auto in place of a more complex type specification, if the compiler can infer the type
+template<> template<>
+void cpp_features_test_object_t::test<2>()
+{
+ std::vector<S32> numbers{3,6,9};
+
+ // auto element
+ auto& aval = numbers[1];
+ ensure("auto element", aval==6);
+
+ // auto iterator (non-const)
+ auto it = numbers.rbegin();
+ *it += 1;
+ S32 val = *it;
+ ensure("auto iterator", val==10);
+}
+
+// range for
+//
+// https://en.cppreference.com/w/cpp/language/range-for
+//
+// Can iterate over containers without explicit iterator
+template<> template<>
+void cpp_features_test_object_t::test<3>()
+{
+
+ // Traditional iterator for with container
+ //
+ // Problems:
+ // * Have to create a new variable for the iterator, which is unrelated to the problem you're trying to solve.
+ // * Redundant and somewhat fragile. Have to make sure begin() and end() are both from the right container.
+ std::vector<S32> numbers{3,6,9};
+ for (auto it = numbers.begin(); it != numbers.end(); ++it)
+ {
+ auto& n = *it;
+ n *= 2;
+ }
+ ensure("iterator for vector", numbers[2]==18);
+
+ // Range for with container
+ //
+ // Under the hood, this is doing the same thing as the traditional
+ // for loop above. Still uses begin() and end() but you don't have
+ // to access them directly.
+ std::vector<S32> numbersb{3,6,9};
+ for (auto& n: numbersb)
+ {
+ n *= 2;
+ }
+ ensure("range for vector", numbersb[2]==18);
+
+ // Range for over a C-style array.
+ //
+ // This is handy because the language determines the range automatically.
+ // Getting this right manually is a little trickier.
+ S32 pows[] = {1,2,4,8,16};
+ S32 sum{};
+ for (const auto& v: pows)
+ {
+ sum += v;
+ }
+ ensure("for C-array", sum==31);
+}
+
+// override specifier
+//
+// https://en.cppreference.com/w/cpp/language/override
+//
+// Specify that a particular class function is an override of a virtual function.
+// Benefits:
+// * Makes code somewhat easier to read by showing intent.
+// * Prevents mistakes where you think something is an override but it doesn't actually match the declaration in the parent class.
+// Drawbacks:
+// * Some compilers require that any class using override must use it consistently for all functions.
+// This makes switching a class to use override a lot more work.
+
+class Foo
+{
+public:
+ virtual bool is_happy() const = 0;
+};
+
+class Bar: public Foo
+{
+public:
+ bool is_happy() const override { return true; }
+ // Override would fail: non-const declaration doesn't match parent
+ // bool is_happy() override { return true; }
+ // Override would fail: wrong name
+ // bool is_happx() override { return true; }
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<4>()
+{
+ Bar b;
+ ensure("override", b.is_happy());
+}
+
+// final
+//
+// https://en.cppreference.com/w/cpp/language/final: "Specifies that a
+// virtual function cannot be overridden in a derived class or that a
+// class cannot be inherited from."
+
+class Vehicle
+{
+public:
+ virtual bool has_wheels() const = 0;
+};
+
+class WheeledVehicle: public Vehicle
+{
+public:
+ virtual bool has_wheels() const final override { return true; }
+};
+
+class Bicycle: public WheeledVehicle
+{
+public:
+ // Error: can't override final version in WheeledVehicle
+ // virtual bool has_wheels() override const { return true; }
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<5>()
+{
+ Bicycle bi;
+ ensure("final", bi.has_wheels());
+}
+
+// deleted function declaration
+//
+// https://en.cppreference.com/w/cpp/language/function#Deleted_functions
+//
+// Typical case: copy constructor doesn't make sense for a particular class, so you want to make
+// sure the no one tries to copy-construct an instance of the class, and that the
+// compiler won't generate a copy constructor for you automatically.
+// Traditional fix is to declare a
+// copy constructor but never implement it, giving you a link-time error if anyone tries to use it.
+// Now you can explicitly declare a function to be deleted, which has at least two advantages over
+// the old way:
+// * Makes the intention clear
+// * Creates an error sooner, at compile time
+
+class DoNotCopy
+{
+public:
+ DoNotCopy() {}
+ DoNotCopy(const DoNotCopy& ref) = delete;
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<6>()
+{
+ DoNotCopy nc; // OK, default constructor
+ //DoNotCopy nc2(nc); // No, can't copy
+ //DoNotCopy nc3 = nc; // No, this also calls copy constructor (even though it looks like an assignment)
+}
+
+// defaulted function declaration
+//
+// https://en.cppreference.com/w/cpp/language/function#Function_definition
+//
+// What about the complementary case to the deleted function declaration, where you want a copy constructor
+// and are happy with the default implementation the compiler will make (memberwise copy).
+// Now you can explicitly declare that too.
+// Usage: I guess it makes the intent clearer, but otherwise not obviously useful.
+class DefaultCopyOK
+{
+public:
+ DefaultCopyOK(): mVal(123) {}
+ DefaultCopyOK(const DefaultCopyOK&) = default;
+ S32 val() const { return mVal; }
+private:
+ S32 mVal;
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<7>()
+{
+ DefaultCopyOK d; // OK
+ DefaultCopyOK d2(d); // OK
+ DefaultCopyOK d3 = d; // OK
+ ensure("default copy d", d.val()==123);
+ ensure("default copy d2", d.val()==d2.val());
+ ensure("default copy d3", d.val()==d3.val());
+}
+
+// initialize class members inline
+//
+// https://en.cppreference.com/w/cpp/language/data_members#Member_initialization
+//
+// Default class member values can be set where they are declared, using either brackets or =
+
+// It is preferred to skip creating a constructor if all the work can be done by inline initialization:
+// http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#c45-dont-define-a-default-constructor-that-only-initializes-data-members-use-in-class-member-initializers-instead
+//
+class InitInline
+{
+public:
+ S32 mFoo{10};
+};
+
+class InitInlineWithConstructor
+{
+public:
+ // Here mFoo is not specified, so you will get the default value of 10.
+ // mBar is specified, so 25 will override the default value.
+ InitInlineWithConstructor():
+ mBar(25)
+ {}
+
+ // Default values set using two different styles, same effect.
+ S32 mFoo{10};
+ S32 mBar = 20;
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<8>()
+{
+ InitInline ii;
+ ensure("init member inline 1", ii.mFoo==10);
+
+ InitInlineWithConstructor iici;
+ ensure("init member inline 2", iici.mFoo=10);
+ ensure("init member inline 3", iici.mBar==25);
+}
+
+// constexpr
+//
+// https://en.cppreference.com/w/cpp/language/constexpr
+//
+// Various things can be computed at compile time, and flagged as constexpr.
+constexpr S32 compute2() { return 2; }
+
+constexpr S32 ce_factorial(S32 n)
+{
+ if (n<=0)
+ {
+ return 1;
+ }
+ else
+ {
+ return n*ce_factorial(n-1);
+ }
+}
+
+template<> template<>
+void cpp_features_test_object_t::test<9>()
+{
+ S32 val = compute2();
+ ensure("constexpr 1", val==2);
+
+ // Compile-time factorial. You used to need complex templates to do something this useless.
+ S32 fac5 = ce_factorial(5);
+ ensure("constexpr 2", fac5==120);
+}
+
+// static assert
+//
+// https://en.cppreference.com/w/cpp/language/static_assert
+//
+// You can add asserts to be checked at compile time. The thing to be checked must be a constexpr.
+// There are two forms:
+// * static_assert(expr);
+// * static_assert(expr, message);
+//
+// Currently only the 2-parameter form works on windows. The 1-parameter form needs a flag we don't set.
+
+template<> template<>
+void cpp_features_test_object_t::test<10>()
+{
+ // static_assert(ce_factorial(6)==720); No, needs a flag we don't currently set.
+ static_assert(ce_factorial(6)==720, "bad factorial"); // OK
+}
+
+// type aliases
+//
+// https://en.cppreference.com/w/cpp/language/type_alias
+//
+// You can use the "using" statement to create simpler templates that
+// are aliases for more complex ones. "Template typedef"
+
+// This makes stringmap<T> an alias for std::map<std::string, T>
+template<typename T>
+using stringmap = std::map<std::string, T>;
+
+template<> template<>
+void cpp_features_test_object_t::test<11>()
+{
+ stringmap<S32> name_counts{ {"alice", 3}, {"bob", 2} };
+ ensure("type alias", name_counts["bob"]==2);
+}
+
+// Other possibilities:
+
+// nullptr
+
+// class enums
+
+// std::unique_ptr and make_unique
+
+// std::shared_ptr and make_shared
+
+// lambdas
+
+// perfect forwarding
+
+// variadic templates
+
+// std::thread
+
+// std::mutex
+
+// thread_local
+
+// rvalue reference &&
+
+// move semantics
+
+// std::move
+
+// string_view
+
+} // namespace tut
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index adac7af712..41da8fa328 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -616,11 +616,9 @@ class WindowsManifest(ViewerManifest):
# CEF files common to all configurations
with self.prefix(src=os.path.join(pkgdir, 'resources')):
- self.path("cef.pak")
- self.path("cef_100_percent.pak")
- self.path("cef_200_percent.pak")
- self.path("cef_extensions.pak")
- self.path("devtools_resources.pak")
+ self.path("chrome_100_percent.pak")
+ self.path("chrome_200_percent.pak")
+ self.path("resources.pak")
self.path("icudtl.dat")
with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
@@ -683,11 +681,6 @@ class WindowsManifest(ViewerManifest):
self.path("libvlccore.dll")
self.path("plugins/")
- # pull in the crash logger from other projects
- # tag:"crash-logger" here as a cue to the exporter
- self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
- dst="win_crash_logger.exe")
-
if not self.is_packaging_viewer():
self.package_file = "copied_deps"
@@ -1068,10 +1061,8 @@ class DarwinManifest(ViewerManifest):
# our apps
executable_path = {}
- for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
- # plugin launcher
- (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
- ):
+ embedded_apps = [ (os.path.join("llplugin", "slplugin"), "SLPlugin.app") ]
+ for app_bld_dir, app in embedded_apps:
self.path2basename(os.path.join(os.pardir,
app_bld_dir, self.args['configuration']),
app)
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 87536e146b..251100867f 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -13,7 +13,7 @@ include(LLXML)
include(Linking)
include(Tut)
include(LLAddBuildTest)
-
+include(bugsplat)
include(GoogleMock)
include_directories(
@@ -83,6 +83,10 @@ list(APPEND test_SOURCE_FILES ${test_HEADER_FILES})
add_executable(lltest ${test_SOURCE_FILES})
+if (USE_BUGSPLAT)
+ set_target_properties(lltest PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
+endif (USE_BUGSPLAT)
+
target_link_libraries(lltest
${LEGACY_STDIO_LIBS}
${LLDATABASE_LIBRARIES}
diff --git a/indra/win_crash_logger/README.txt b/indra/win_crash_logger/README.txt
new file mode 100644
index 0000000000..6932a8d9c3
--- /dev/null
+++ b/indra/win_crash_logger/README.txt
@@ -0,0 +1,3 @@
+This component is no longer used in Linden Lab builds.
+Change requests to support continued use by open source
+builds are welcome.
diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
index 267224a79b..0cbe0b0d17 100644
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ b/indra/win_crash_logger/llcrashloggerwindows.cpp
@@ -498,7 +498,7 @@ bool LLCrashLoggerWindows::frame()
MSG msg;
memset(&msg, 0, sizeof(msg));
- while (!LLApp::isQuitting() && GetMessage(&msg, NULL, 0, 0))
+ while (!LLApp::isExiting() && GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
diff --git a/scripts/metrics/viewerstats.py b/scripts/metrics/viewerstats.py
new file mode 100755
index 0000000000..f7be3d967e
--- /dev/null
+++ b/scripts/metrics/viewerstats.py
@@ -0,0 +1,226 @@
+#!runpy.sh
+
+"""\
+
+This module contains code for analyzing ViewerStats data as uploaded by the viewer.
+
+$LicenseInfo:firstyear=2021&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2021, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+$/LicenseInfo$
+"""
+
+import argparse
+import numpy as np
+import pandas as pd
+import json
+from collections import Counter, defaultdict
+from llbase import llsd
+import io
+import re
+import os
+import sys
+
+def show_stats_by_key(recs,indices,settings_sd = None):
+ result = ()
+ cnt = Counter()
+ per_key_cnt = defaultdict(Counter)
+ for r in recs:
+ try:
+ d = r
+ for idx in indices:
+ d = d[idx]
+ for k,v in d.items():
+ if isinstance(v,dict):
+ continue
+ cnt[k] += 1
+ if isinstance(v,list):
+ v = tuple(v)
+ per_key_cnt[k][v] += 1
+ except Exception as e:
+ print "err", e
+ print "d", d, "k", k, "v", v
+ raise
+ mc = cnt.most_common()
+ print "========================="
+ keyprefix = ""
+ if len(indices)>0:
+ keyprefix = ".".join(indices) + "."
+ for i,m in enumerate(mc):
+ k = m[0]
+ bigc = m[1]
+ unset_cnt = len(recs) - bigc
+ kmc = per_key_cnt[k].most_common(5)
+ print i, keyprefix+str(k), bigc
+ if settings_sd is not None and k in settings_sd and "Value" in settings_sd[k]:
+ print " ", "default",settings_sd[k]["Value"],"count",unset_cnt
+ for v in kmc:
+ print " ", "value",v[0],"count",v[1]
+ if settings_sd is not None:
+ print "Total keys in settings", len(settings_sd.keys())
+ unused_keys = list(set(settings_sd.keys()) - set(cnt.keys()))
+ unused_keys_non_str = [k for k in unused_keys if settings_sd[k]["Type"] != "String"]
+ unused_keys_str = [k for k in unused_keys if settings_sd[k]["Type"] == "String"]
+
+ # Things that no one in the sample has set to a non-default value. Possible candidates for removal.
+ print "\nUnused_keys_non_str", len(unused_keys_non_str)
+ print "======================"
+ print "\n".join(sorted(unused_keys_non_str))
+
+ # Strings are not currently logged, so we have no info on usage.
+ print "\nString keys (usage unknown)", len(unused_keys_str)
+ print "======================"
+ print "\n".join(sorted(unused_keys_str))
+
+ # Things that someone has set but that aren't recognized settings.
+ unrec_keys = list(set(cnt.keys()) - set(settings_sd.keys()))
+ print "\nUnrecognized keys", len(unrec_keys)
+ print "======================"
+ print "\n".join(sorted(unrec_keys))
+
+ result = (settings_sd.keys(), unused_keys_str, unused_keys_non_str, unrec_keys)
+ return result
+
+def parse_settings_xml(fname):
+ # assume we're in scripts/metrics
+ fname = "../../indra/newview/app_settings/" + fname
+ with open(fname,"r") as f:
+ contents = f.read()
+ return llsd.parse_xml(contents)
+
+def read_raw_settings_xml(fname):
+ # assume we're in scripts/metrics
+ fname = "../../indra/newview/app_settings/" + fname
+ contents = None
+ with open(fname,"r") as f:
+ contents = f.read()
+ return contents
+
+def write_settings_xml(fname, contents):
+ # assume we're in scripts/metrics
+ fname = "../../indra/newview/app_settings/" + fname
+ with open(fname,"w") as f:
+ f.write(llsd.format_pretty_xml(contents))
+ f.close()
+
+def write_raw_settings_xml(fname, string):
+ # assume we're in scripts/metrics
+ fname = "../../indra/newview/app_settings/" + fname
+ with io.open(fname,"w", newline='\n') as f:
+ f.write(string.decode('latin1'))
+ f.close()
+
+def remove_settings(string, to_remove):
+ for r in to_remove:
+ subs_str = r"<key>" + r + r"<.*?</map>\n"
+ string = re.sub(subs_str,"",string,flags=re.S|re.DOTALL)
+ return string
+
+def get_used_strings(root_dir):
+ used_str = set()
+ skipped_ext = set()
+ for dir_name, sub_dir_list, file_list in os.walk(root_dir):
+ for fname in file_list:
+ if fname in ["settings.xml", "settings.xml.edit", "settings_per_account.xml"]:
+ print "skip", fname
+ continue
+ (base,ext) = os.path.splitext(fname)
+ #if ext not in [".cpp", ".hpp", ".h", ".xml"]:
+ # skipped_ext.add(ext)
+ # continue
+
+ full_name = os.path.join(dir_name,fname)
+
+ with open(full_name,"r") as f:
+ #print full_name
+ lines = f.readlines()
+ for l in lines:
+ ms = re.findall(r'[>\"]([A-Za-z0-9_]+)[\"<]',l)
+ for m in ms:
+ #print "used_str",m
+ used_str.add(m)
+ print "skipped extensions", skipped_ext
+ print "got used_str", len(used_str)
+ return used_str
+
+
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(description="process tab-separated table containing viewerstats logs")
+ parser.add_argument("--verbose", action="store_true",help="verbose flag")
+ parser.add_argument("--preferences", action="store_true", help="analyze preference info")
+ parser.add_argument("--remove_unused", action="store_true", help="remove unused preferences")
+ parser.add_argument("--column", help="name of column containing viewerstats info")
+ parser.add_argument("infiles", nargs="+", help="name of .tsv files to process")
+ args = parser.parse_args()
+
+ for fname in args.infiles:
+ print "process", fname
+ df = pd.read_csv(fname,sep='\t')
+ #print "DF", df.describe()
+ jstrs = df['RAW_LOG:BODY']
+ #print "JSTRS", jstrs.describe()
+ recs = []
+ for i,jstr in enumerate(jstrs):
+ recs.append(json.loads(jstr))
+ show_stats_by_key(recs,[])
+ show_stats_by_key(recs,["agent"])
+ if args.preferences:
+ print "\nSETTINGS.XML"
+ settings_sd = parse_settings_xml("settings.xml")
+ #for skey,svals in settings_sd.items():
+ # print skey, "=>", svals
+ (all_str,_,_,_) = show_stats_by_key(recs,["preferences","settings"],settings_sd)
+ print
+
+ #print "\nSETTINGS_PER_ACCOUNT.XML"
+ #settings_pa_sd = parse_settings_xml("settings_per_account.xml")
+ #show_stats_by_key(recs,["preferences","settings_per_account"],settings_pa_sd)
+
+ if args.remove_unused:
+ # walk codebase looking for strings
+ all_str_set = set(all_str)
+ used_strings = get_used_strings("../../indra")
+ used_strings_set = set(used_strings)
+ unref_strings = all_str_set-used_strings_set
+ # Some settings names are generated by appending to a prefix. Need to look for this case.
+ prefix_used = set()
+ print "checking unref_strings", len(unref_strings)
+ for u in unref_strings:
+ for k in range(6,len(u)):
+ prefix = u[0:k]
+ if prefix in all_str_set and prefix in used_strings_set:
+ prefix_used.add(u)
+ #print "PREFIX_USED",u,prefix
+ print "PREFIX_USED", len(prefix_used), ",".join(list(prefix_used))
+ print
+ unref_strings = unref_strings - prefix_used
+
+ print "\nUNREF_IN_CODE " + str(len(unref_strings)) + "\n"
+ print "\n".join(list(unref_strings))
+ settings_str = read_raw_settings_xml("settings.xml")
+ # Do this via direct string munging to generate minimal changeset
+ settings_edited = remove_settings(settings_str,unref_strings)
+ write_raw_settings_xml("settings.xml.edit",settings_edited)
+
+
+
+
+
+