Compare commits

...

184 Commits

Author SHA1 Message Date
Liru Færs
788b83bff3 Woops, thanks for catching this, Shyotl! 2020-04-18 19:15:49 -04:00
Liru Færs
c201ac90ba Track log names in a json map AND Fix processing local log load as system
Update old style callbacks for chatFromLogFile functions to lambdas
Keep track of people's log's name using their IDs, but don't rename.
Fallback on ID if name is empty (if the grid is a meanie)
Also track group names this way, sometimes those change.
Prefer std::array, since we're in the area.
2020-04-18 00:17:05 -04:00
Shyotl
af3c66ad08 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-16 02:23:32 -05:00
Shyotl
9bffc4bb82 Attempt to squash spatial partition crash. 2020-04-16 00:52:55 -05:00
Shyotl
132db6225e Make Debug configuration compile once more. 2020-04-16 00:49:42 -05:00
Shyotl
257086cbfc Revert texture fetching behavior back closer to v3. 2020-04-16 00:36:56 -05:00
Liru Færs
7755f1ec52 Merge branch 'master' of https://github.com/RouterGray/SingularityViewer 2020-04-11 10:28:04 -04:00
Router Gray
c5f1ac808b Fix postcard sends, use cap for user info, stop using 'from' email as per upstream. Mark final and overrides. Thanks Nadira Fairport for reporting & Liru for help. 2020-04-11 09:22:26 -05:00
Liru Færs
1a8660909d Copy Folder ID and Open Folder In New Window for ANY folder 2020-04-10 17:40:06 -04:00
Shyotl
e6826a4c7c Fix 'is typing...' notifications never going away. 2020-04-10 16:28:37 -05:00
Router Gray
801bb8a075 Compile fix, make types agree in terniary in octree. Thanks Liru. 2020-04-10 13:21:57 -05:00
Shyotl
b2c965e22d Do not apply internal windlight parameter scaling on the sliders themselves. 2020-04-09 14:20:55 -05:00
Shyotl
be3cbc642b Update current region debug string upon cap seed request. Carry over seed cap if dead region is replaced with new. 2020-04-09 02:12:36 -05:00
Shyotl
24331d3c90 Prefer LLPointer over potential for dangling LLSpatialGroup pointers. 2020-04-09 01:56:32 -05:00
Shyotl
8a16e6c99f Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-08 18:18:19 -05:00
Shyotl
f36e8fbeca Better crashdump context. 2020-04-08 18:11:09 -05:00
Liru Færs
718ef09adf Fix removing/exporting picks when unable to add more
Wooops, wrote that wrong, must've been tired or something
2020-04-08 09:21:21 -04:00
Liru Færs
6443849ea9 Do not lookup strings in the toolbar per frame, ack! 2020-04-08 08:33:41 -04:00
Liru Færs
cbb7e473ba Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2020-04-08 06:59:48 -04:00
Liru Færs
118957362f Fix mismatched tag 2020-04-08 05:11:11 -04:00
Shyotl
ed7f73769f Potentially fix crash in LLSurface 2020-04-07 23:30:12 -05:00
Liru Færs
ae15dcb318 Merge 41224c57317b6c1b44528aa1dc1f13732cdffe6d from viewer-lion... sorta
Fixes broken default perms message sometimes popping up for certain avs
2020-04-07 16:55:58 -04:00
Liru Færs
c4af22481c Update mesh export code, cause why not. 2020-04-07 15:30:13 -04:00
Liru Færs
ae17f76bb4 Remove now unused LLIMInfo 2020-04-07 10:49:48 -04:00
Liru Færs
7e62d17fda Don't try to use region if it's null for permissions defaults 2020-04-07 05:56:06 -04:00
Liru Færs
f9185e8bc8 Fix mutelist popping up, I think
LLMuteList::add should return false if nothing new was added
2020-04-07 05:55:24 -04:00
Liru Færs
1361f9b57d Simplify selection of mute 2020-04-07 04:29:45 -04:00
Liru Færs
b86eae026b Sync to fix using gMessageSystem when it may not have the right message 2020-04-07 04:29:20 -04:00
Liru Færs
79d938a4f4 Sync LLMuteList code with upstream 2020-04-07 02:51:08 -04:00
Liru Færs
23068a70a2 Select Mute when muting object via Object profile 2020-04-06 07:53:42 -04:00
Shyotl
0aa5e0bb88 Close 'default permissions' window on client disconnect. Nonfunctional after that point anyhow. Also applying setting crashes due to null region after dc. 2020-04-05 14:56:35 -05:00
Router Gray
5040275969 [CMake] Releases shouldn't speak Greek. 2020-04-04 06:47:39 -05:00
Liru Færs
1daccf40ee Move the FMOD Powered By text, for Torric and others 2020-04-04 07:28:19 -04:00
Shyotl
4fd302286b Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-03 06:02:48 -05:00
Shyotl
18f9f19e61 Textures mid-decode potentially processing of other textures until complete. Disabled UDP texture fetch fallback when connected to official grid. 2020-04-03 06:01:58 -05:00
Liru Færs
1de6d4461a Add missing EmergencyTeleportSeconds preference to System->Security
Thanks for the heads up about this missing preferences, and for the
Spanish translation, Damian!
2020-04-03 02:53:41 -04:00
Shyotl
4198f47ab6 Fix header breakage in debug/relwithdebug 2020-04-03 00:33:19 -05:00
Shyotl
d9049ba342 Handle AISAPI throttling and status 410 a bit better. 2020-04-02 21:47:07 -05:00
Shyotl
f75ac3e4c2 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-02 20:09:53 -05:00
Liru Færs
06698deaca A couple more sim->region changes 2020-04-02 21:08:23 -04:00
Shyotl
445eb29bd3 Bring aisapi handling closer to LL (code 499 retry, match timeout values, etc) 2020-04-02 20:07:55 -05:00
Shyotl
cc034f6841 Fix inventory scrolling issue when navigating via keyboard. 2020-04-02 20:03:08 -05:00
Liru Færs
3c368651f1 Update crashpad, thanks Rye! 2020-04-02 20:39:01 -04:00
Damian Zhaoying
321730e384 More translations fixes in Area search and menu list owners. 2020-04-02 03:02:23 -03:00
Damian Zhaoying
c2fd88670f Fix some remaining spanish translations. 2020-04-02 02:36:20 -03:00
Liru Færs
7b03103a1f April Fools!
Ha, goteem
2020-04-01 20:52:44 -04:00
Liru Færs
ac3e19c91a Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2020-04-01 20:47:23 -04:00
Liru Færs
4c7d2224e3 Fix reverted xml change, fix formatting 2020-04-01 20:43:00 -04:00
Shyotl
3ab800d99e Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-04-01 19:26:41 -05:00
Shyotl
332cef0f84 Disable debug logging unless RelWithDeb 2020-04-01 19:26:23 -05:00
Damian Zhaoying
9de6d7627b A lot of updates and fixes for spanish language translations. 2020-04-01 20:44:41 -03:00
Liru Færs
98b42e88c1 Fix SV-2282: Incorrect terminology for TP Sound preference UI 2020-04-01 06:56:51 -04:00
Liru Færs
e642e9561a The sim is actually the region 2020-04-01 04:42:34 -04:00
Liru Færs
77f500cb64 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2020-04-01 01:59:42 -04:00
Liru Færs
d04a8fc677 Merge branch 'master' of https://github.com/RouterGray/SingularityViewer 2020-04-01 01:59:32 -04:00
Liru Færs
6028ae7b61 Fix group notices: Have a background for the header for certain skins. 2020-04-01 01:56:58 -04:00
Shyotl
347c2cbd8b Fall in line with LL octree code. 2020-03-31 19:07:55 -05:00
Router Gray
919ffb314b [UI] Add missing 'AlreadyInGroup' to strings.xml 2020-03-30 15:24:28 -05:00
Router Gray
c033d69d54 [Linux] More follow-through on earlier manifest tuning, make always really mean always. 2020-03-30 03:06:21 -05:00
Router Gray
356d289972 User request: Add last owner profile button to object inspect. 2020-03-29 19:16:52 -05:00
Router Gray
eeabbce377 [Lib] Update abseil. (Alchemy sync) 2020-03-29 16:39:16 -05:00
Router Gray
0b992fdd46 [Lib] Update nlohmann json and switch it to FetchContent instead of prebuilts. (Alchemy sync) 2020-03-29 16:38:53 -05:00
Router Gray
a7e56d2af9 Fix an accident in a ternary. 2020-03-29 16:31:40 -05:00
Router Gray
b10619e4d8 [Linux] Don't strip binaries, even when building release, unless packaging. Makes quick debugging in the dev checkout easier.
This may need more work if we want to support building an 'install' target, bypassing packaging, but I never hear of anyone doing that.  I'll address it if needed.
2020-03-29 15:24:10 -05:00
Router Gray
74518f299c Merge remote-tracking branch 'github-liru/master' 2020-03-29 15:21:22 -05:00
Liru Færs
407b527a55 [XPTools] Fix linux crash bug, make Cancel button close Experiences floater 2020-03-29 00:43:21 -04:00
Liru Færs
b21cc835b2 Clean up old Experience UI port code 2020-03-28 16:38:14 -04:00
Shyotl
4de8c3a38e Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-03-27 02:56:20 -05:00
Shyotl
72d8b8f78c Potentially harden against region teardown crash. Screw with branching to delve more information from callstacks since dynamic annotations don't seem to work with sentry.io using crashpad lib... sadface. 2020-03-27 02:55:12 -05:00
Liru Færs
45f4f601bf nopaque 2020-03-27 02:35:06 -04:00
Liru Færs
731283aa0b Friendship accepted notifications as tips with linked names 2020-03-27 00:51:45 -04:00
Liru Færs
89ce328ba5 Fix script dialogs showing UI SLURLs when SinguReplaceLinks is false
All interface SLURLs should be force replaced.
Also fixes text boxes not respecting setting at all
2020-03-26 23:31:52 -04:00
Liru Færs
28e5270d87 All agent SLURLs should use the name system names, not just profile ones. 2020-03-25 23:57:05 -04:00
Shyotl
4a237de72a Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2020-03-25 22:37:23 -05:00
Shyotl
e91aac1dd9 For science. Let's see if sentry.io accepts these annotations... 2020-03-25 22:35:29 -05:00
Liru Færs
7cab44a17d Merge branch 'master' of https://github.com/RouterGray/SingularityViewer 2020-03-25 05:47:34 -04:00
Liru Færs
cf57624688 Fix IsNearby check having invalid logic and hiding options because of it 2020-03-24 22:41:23 -04:00
Liru Færs
c7448f290d Fix inverted logic for benefits on opensim 2020-03-24 17:42:21 -04:00
Liru Færs
55f9937238 Fix looping over empty age strings on OpenSim, no longer retry on SL 2020-03-24 16:27:16 -04:00
Liru Færs
ac1ef4d1ba Hide temp upload on SL 2020-03-23 21:39:08 -04:00
Liru Færs
ee1baafb59 Actually Delete LLView copy constructor 2020-03-23 21:20:21 -04:00
Liru Færs
9522e385cd Merge viewer-benefits
Replace MAX_AGENT_ATTACHMENTS with sim based response
Replace max groups with benefits based response
Upload costs are now handled by sim response
Removed no-longer-needed lleconomy files and classes
Removed dead fields from hippolimits and hippogridmanager
Also removed lame LL code that is redundant and silly

On non SL grids, when values are not provided for benefits, they will be
set to the values granting maximum liberty.
Old standardized responses still work when benefits aren't implemented.
2020-03-23 20:15:59 -04:00
Router Gray
a9b047b168 Minor compile fixes: move a declaration out of a namespace, add an include 2020-03-23 11:47:17 -05:00
Liru Færs
8c6e6143c2 Fix accidental paste in aosystem init 2020-03-23 09:11:13 -04:00
Liru Færs
0704876dfd Comment out unused macros in llviewerregion.h 2020-03-23 09:10:46 -04:00
Liru Færs
54b75a3219 Add SinguOwnerSayAsErrors to make llOwnerSay spew to debug console instead 2020-03-23 08:44:25 -04:00
Liru Færs
11d59d1b00 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer
# Conflicts:
#	indra/newview/llsurface.cpp
2020-03-23 01:04:25 -04:00
Liru Færs
4e042db404 Merge branch 'master' of https://github.com/RouterGray/SingularityViewer 2020-03-23 01:03:25 -04:00
Liru Færs
0f6285b2e9 Split up floaterao.* into aosystem.* and aostate.h, also further refactor 2020-03-22 15:02:08 -04:00
Liru Færs
a3d2107bfd Fix an oopsie woopsie, thanks bready doggy 2020-03-22 10:46:30 -04:00
Liru Færs
a66c91bc5a Labels for agent slurls should use the default name system 2020-03-22 10:36:54 -04:00
Liru Færs
4602602a5f Link owner name in inventory offers from objects 2020-03-22 10:03:51 -04:00
Liru Færs
0511d5903a erase iters properly, please 2020-03-22 09:53:47 -04:00
Liru Færs
7597ce3b37 Force Swim button for AO, for when you wanna swim above water
Force Swim forces swims to be enabled
2020-03-22 09:52:54 -04:00
Liru Færs
7509d929d8 Make everyone upset! Reorganize group notices!
Feature request: clickable names and group names
Remove dead space in group notices that has always plagued us
2020-03-22 09:07:46 -04:00
Liru Færs
c7e03600aa Fix constant reallocation of texture fetch command queue because...who..uses a vector..for a fifo...
By Rye, thanks!
2020-03-22 07:46:20 -04:00
Liru Færs
4871f5ed8e AO Refactor
Should fix AO not turning on without opening floater first

Cleans up code
Reduces memory footprint, especially when not in use
Removes unused functions and parameters
Decouples AO from Floater class (AOSystem)
Removes duplicate Idle state
Formalizes singleton patterns of globals
Centralizes override handling into override structs
Fall back on simple english notecard explanation when missing config ini
Fixes sitting override playing when sitting is disabled (and acting weird)
Moves the bulk of override handling into override structs
No longer state-based, now tracks using per-struct playing field
2020-03-22 07:42:24 -04:00
Router Gray
e5a6f1e2d9 [CMake Linux] Fix my being too rushed in Copy3rdParty, restore openal 2020-03-16 03:38:55 -05:00
Shyotl
a29491658b Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git
# Conflicts:
#	indra/llmath/lloctree.h
#	indra/newview/llsurface.cpp
2020-03-15 00:53:20 -05:00
Shyotl
26976b715d Fixup minor use after free issues, and improper mutex usage in meshrepo. Also fixed some compiler warnings. 2020-03-15 00:46:57 -05:00
Liru Færs
8d564d6ed1 Follow Pilot algorithm tweak: Fly if already flying or target is above 2020-03-10 17:00:02 -04:00
Liru Færs
18fbac26dc Correct comment in follow pilot code 2020-03-10 16:32:14 -04:00
Liru Færs
9f82933149 Reduce repeated follow pilot code 2020-03-10 16:31:51 -04:00
Liru Færs
9b7aa959b0 Fix unresolved links in caution notifications 2020-03-10 16:30:37 -04:00
Liru Færs
1c46c26e6b Notifications with tooltips on buttons, for when text is too long! 2020-03-10 16:29:10 -04:00
Liru Færs
506c6aaa9e Use INetC instead of NSISdl, thanks Rye! 2020-03-10 16:27:48 -04:00
Liru Færs
dd61d475cb Prevent use of outdated notecard import by removing it from LLTextEditor
LLViewerTextEditor properly overrides this anyway.
2020-03-05 04:09:46 -05:00
Liru Færs
6e5eed7957 Fix focus on Object Owners
Just noticed this must've slipped out of a previous commit
2020-03-04 15:45:04 -05:00
Liru Færs
7859c0a191 Fix the ancient way of magic text box hack wherein multiple buttons works
Also when muting scripts through notification, properly pop mute dialog
2020-03-03 22:02:44 -05:00
Liru Færs
ef46d21582 Final 2020-03-03 21:51:54 -05:00
Router Gray
5071c1e0cf Merge remote-tracking branch 'github-liru/master' into NixTesting 2020-03-01 09:42:35 -06:00
Router Gray
ecd52a9e1a [Cmake] Comment out unused llplugincookiestore. 2020-03-01 09:42:00 -06:00
Router Gray
0a6a47a099 [Linux] Use system X11. 2020-03-01 09:42:00 -06:00
Router Gray
9880fe225e [Linux] Use system libraries for dbus-glib, gtk-atk-pango-glib, and ogg-vorbis. 2020-03-01 09:42:00 -06:00
Liru Færs
5d44552a60 Allow UI scale values as low as .5 to better meet HiDPI needs
Adapted from Rye's work on Alchemy, Thanks!
2020-03-01 09:21:59 -05:00
Liru Færs
ffa32f8c98 Fix linux compile 2020-03-01 03:51:47 -05:00
Liru Færs
b7086a993d Merge branch 'master' of git://github.com/Shyotl/SingularityViewer
# Conflicts:
#	indra/llmath/lloctree.h
#	indra/newview/llsurface.cpp
2020-03-01 03:39:30 -05:00
Shyotl
d2d172f6ec Allow oversized images when performing raw snapshots. 2020-02-29 22:51:45 -06:00
Shyotl
34f6ea4db2 Rework LLSurface[Patch]. Abuse weak_ptr for now. Rewrote connectNeighbor. LLSurfacePatch no longer calls parent LLSurface with this poiter, instead parent surface just handles return value and controls its own behavior [Requred for weak_ptr/shared_ptr change. 2020-02-29 22:33:51 -06:00
Shyotl
d8c4db17f2 Make gcc happy again.. 2020-02-29 22:15:46 -06:00
Shyotl
c340dde03d Speculative fixes. 2020-02-29 22:15:27 -06:00
Liru Færs
e502b87b63 Ooops, forgot to save the rewrite of this that actually fixes it 2020-02-29 11:16:46 -05:00
Liru Færs
d6f320fb5e Clean up Object SLURL right click menu with a few submenus 2020-02-29 08:20:50 -05:00
Liru Færs
e4eca079e6 Allow right clicking object UI labels to interact with their owners! 2020-02-29 08:19:41 -05:00
Liru Færs
68ceac3678 llDialog & llTextBox with linked owner name and object name 2020-02-29 06:46:20 -05:00
Liru Færs
991d603a0c Don't copy around strings and UUIDs, LL... pls 2020-02-29 05:57:36 -05:00
Liru Færs
74a6f7382a When possible, populate the owner id of our llviewerobjects 2020-02-29 05:51:07 -05:00
Liru Færs
9264482dc3 Small patch to french translation, thanks Nomade 2020-02-29 04:47:53 -05:00
Liru Færs
1a61c49fc7 Display name change notifications that link to the user 2020-02-29 04:47:17 -05:00
Liru Færs
c2480d7227 When muting an object via pie menu, select it in the mute floater 2020-02-29 04:46:15 -05:00
Liru Færs
72b5976605 Merge to fix missing agent slurl handler for removefriend and (un)block 2020-02-29 04:45:37 -05:00
Liru Færs
1b742aa933 Menu finals and overrides 2020-02-28 22:33:37 -05:00
Liru Færs
9412f631fa Object->Derender from Object UIs 2020-02-28 01:31:34 -05:00
Router Gray
be07df3043 [Lib] Update Linux dullahan 2020-02-26 23:54:22 -06:00
Router Gray
8f89127900 [CEF] Catch a missed change for dullahan update. OCDly fix an indentation. 2020-02-26 23:24:36 -06:00
Router Gray
c72059e73f [CMake CEF] How was this even working? Set dependencies and link targets to cef instead of webkit. 2020-02-26 07:21:48 -06:00
Router Gray
2fc2b7c12b Sync some mime types with upstream, also remove erroneous 'video/libvlc' mimetype. There is no such mimetype. 2020-02-26 07:05:41 -06:00
Liru Færs
a652cb4f0a Collaboration between myself and Router the Gray to Flinux 2020-02-25 13:25:12 -05:00
Liru Færs
16b8980d28 Fix the new window inventory folder floater, and opt it to squeak! 2020-02-25 12:52:41 -05:00
Liru Færs
841a55c266 Remove duplicate setText line that was failing anyway. 2020-02-25 10:23:37 -05:00
Liru Færs
2aa6adfd46 Pip, Squeak. 2020-02-25 08:04:31 -05:00
Liru Færs
bac0b3d745 Update FMOD Studio to 2.00.07 2020-02-25 06:55:05 -05:00
Liru Færs
b08b597397 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer
# Conflicts:
#	indra/llcommon/llsd.cpp
#	indra/llcommon/llsdserialize.cpp
#	indra/newview/llspeakers.cpp
#	indra/newview/llviewermessage.cpp
2020-02-25 06:51:41 -05:00
Shyotl
25cb81221e Don't use clamp mode on av mesh. 2020-02-25 02:36:32 -06:00
Liru Færs
4f5749878f Merge branch 'master' of https://github.com/RouterGray/SingularityViewer
# Conflicts:
#	indra/newview/llexperiencelog.cpp
2020-02-25 03:33:49 -05:00
Liru Færs
2aa3ba4d36 Fix crashes that were reported when using object right click menu
Menu entries that cannot work when an object vanishes will gracefully fail.
2020-02-25 03:29:41 -05:00
Liru Færs
6a2421e2e7 Fix dumb build warning on windows 2020-02-25 03:27:37 -05:00
Liru Færs
e78061b077 Hide group voting tab on secondlife, it is no longer used there. 2020-02-25 03:27:06 -05:00
Liru Færs
379f97e15a Buncha small fixes, mainly from alchemy
Update firestorm jira url
Maintain sorting and and scroll position when refreshing region tracker
Add missing CrashHostUrl setting
And a buncha other tinies, probably a crash fix or two.
2020-02-25 03:26:33 -05:00
Liru Færs
2afd2c500b Update VLC and Dullahan. Update vcredist deployment. Thanks Alchemy! 2020-02-25 03:21:27 -05:00
Liru Færs
0c3e144547 Properly sized FMOD logo, 40 pixels high. Inspired by Alchemy, thanks Rye!¶ 2020-02-25 03:08:01 -05:00
Liru Færs
842d1b8d93 Add LLIMProcessing and support for new message caps! And UserInfo cap!
Also delayed sound support!
Fixed memory leaks and pass by values that LL likes to introduce.
Extended LLCoroResponder to have a responder for Raw strings, also clean it
Adds friend request message logging.
2020-02-25 03:04:58 -05:00
Shyotl
5c2c2a8c01 Minor cleanup. Octree vfunc reduction. Range-based for loops with map/array llsd types. 2020-02-25 01:50:50 -06:00
Router Gray
61f0837114 Make Linux and LLExperienceLog play nice. Thanks Liru. 2020-02-24 17:30:40 -06:00
Router Gray
aa95d8fe3d [LL] Update the login splash page for LL grids. 2020-02-24 06:37:42 -06:00
Router Gray
a52c4779c8 Make event notifications say 'Dismiss' instead of 'Cancel'. 2020-02-23 13:44:24 -06:00
Router Gray
1ece0e6051 [UI] Add Copy Folder UUID to inventory actions 2020-02-19 12:40:33 -06:00
Liru Færs
6a56d048c0 Don't confuse the user by showing loading when refreshing item's experience
Also reorganize some code in that area to be cleaner
2020-02-11 20:19:04 -05:00
Liru Færs
e34999b6a9 Fix missing string for experience profile button tooltip in scripts 2020-02-11 19:49:11 -05:00
Liru Færs
103b2c0f33 Fix layout of item properties floater 2020-02-11 19:07:39 -05:00
Liru Færs
2fe45cb8c2 Fix group inventory receiveds not displaying properly in chat history
Also fix linking to an avatar profile when a group's object gives an item
2020-02-11 18:34:45 -05:00
Liru Færs
64a44d6c1b Fix size and position of folder floaters not being restored from setting 2020-02-11 18:31:47 -05:00
Liru Færs
3073a175d7 Add LiruUseMarkedColor to disable use of mark color in the new places 2020-02-11 17:39:46 -05:00
Liru Færs
3b550c3a93 Fix the Jira URL bug we brought up at the last TPV meeting 2020-02-11 15:13:42 -05:00
Liru Færs
1d2c0cb8c6 Script permission dialogs should link back to the object and its owner 2020-02-11 15:09:48 -05:00
Liru Færs
2f369299c5 Object info with right-clickable owner naame, also improve code overall 2020-02-11 15:06:39 -05:00
Liru Færs
e65b513562 Syncy stuffs 2020-02-11 13:04:05 -05:00
Liru Færs
6959b688be Fix the issue with thin resize space in inventory folder floaters 2020-02-11 12:20:33 -05:00
Liru Færs
7db999d801 Fix copyright being 2019, thanks Del 2020-02-11 12:17:05 -05:00
Liru Færs
703ad01c8b AntiSpam refactor!
Adds SLURLs to antispam notifications
Reduces weight of antispam to either global queue, multiple queues, or none
Renames variables to make more sense
Repositions code, cleans up code, uses modern C++, etc
This fixes a bit of a leak or two, especially with antispam turned off!
Also fixes the endless leak of queue expansion by cleaning up while idle
When changing between global and individual queues, they're now purged.
Also made some improvements to previous commit, woops.
Also fix wrong logic for is_linden and chat source type for objects
2020-02-11 12:16:44 -05:00
Liru Færs
199879aea8 Break out functions for getting object owner, owner and object slurls 2020-02-09 18:52:06 -05:00
Liru Færs
eefa0f07a7 Reduce reused getBOOL 2020-02-09 18:28:48 -05:00
Liru Færs
6e6fb44bdb Fix potential crash, thanks Rye and Testicular! 2020-02-09 18:28:10 -05:00
Liru Færs
0892d14933 Fix debit permission Allow being too long, and remove newlines from it 2020-02-09 04:34:55 -05:00
Liru Færs
400da6ec92 Fix out of order and duplicate preferences 2020-02-09 04:33:20 -05:00
Liru Færs
18539831d1 Request: Just show viewer's short name in update notification, not channel 2020-02-09 04:32:27 -05:00
Liru Færs
9548270306 Buncha tinies
Link name in inventory offer received chat message
Fix shupdate compile missing ; and include from two commits ago
Update links used in menu_viewer.xml, I have things to do today...
And move inventory button on toolbar to between favs and received
2020-02-07 09:00:03 -05:00
Liru Færs
44aec1384a Fix crash in object weights when null selection 2020-02-07 08:03:57 -05:00
Liru Færs
42139835d5 Redo update checker responder to be more like unstable branch 2020-02-07 08:02:44 -05:00
Liru Færs
49f0f8e28f [XP Tools] Further UI beautification
Refix all the panels that weren't good enough.
Fix settingss and default rects
Remove unused
Fix toolbar prefs floater
Use text editors for "URLs" we can't control, they resolve nicer anyway
Fix Texture Ctrl on profile not popping out on click
Fix Maturity string on profile not displaying
Also update about floater credits according to modern data.
2020-02-07 07:48:58 -05:00
Inusaito Sayori
36b75b2398 A Massive Experience Tools (and Unstable Branch) Merge
[XP Tools] Initial merge Cherry Pick

Also modernize llfloaterauction internally, but leave the ui the same for now.
Breaks out script_question_mute() in llviewermessage.cpp to better sync with upstream
Adds support for UnknownScriptQuestion notification (translators need to translate this one~)
RLVa note: Rewrote RLVa permissions handling block just a bit.
Added 13 new capabilities from the XP Tools, I doubt all of them really exist.
Minor update to LLComboBox, decided against implementing LLIconsComboBox for now.
Modified LLExperienceLog::notify to lookup names and display them along with the slurls since our editors don't do that automatically.
Experience tweak: Changed a few notify's to notifytips so that we can click the links to experience profiles from chat instead of via hacked in buttons
Migrated LLFloaterCompileQueue to a proper Instance Tracker so we can call getKey
Modernized LLSD, gives us reverse iterators and the new debugging impl. We needed the reverse iterators.
Experience tweak: Added virtual destructors to responders.
Updated llhandle.h to allow calling getDerivedHandle in public.
Updated LLScrollContainer and LLScrollBar to be more modern.
Added LLFlatListView/flat_list_view from upstream - these don't seem work though?
Added some newer login/logout strings to strings.xml
Thanks for the default timeout policies, Aleric~
To avoid needing to scroll through tabs, about land tabs now are as big as they need to be to display their labels, same on groups
Group Members and Roles has been renamed to just Members because this allows the new Experiences tab enough room to display.
Thanks to Henri Beauchamp (Cool VL Viewer) for the setupList augmentation. (without it, I'd still be stuck)
Thanks to Shyotl for the helpsies~
Added the LSL constants, events, and functions that LL neglected to put in.
Added click callbacks and name lookups for profile linky texts~

Merge is up to 22b4cdc
Old TODO: Get the uis looking nice (profiles? Experiences... floater) - done
Old TODO: Make sure flatlistviews look okay... - Not using
Old TODO: Fix LLFloaterExperiencePicker, right now the panel does not show. - unsure
Old TODO: Remove the llfloaterabout.cpp change. - done

Merges llexperiencecache with upstream and unstable
Introduces LLCoroResponder, TODO: Make everything use this.
Updates Reporter floater to the latest, supports the new cap thingy

Also adds these commits/changes:
[XPTools] Double clicking experiences in namelists should open the profile
Add List.CopyNames support for Experiences
[XP Tools] Some UI work, I'll do more later
[XPTools] More UI Stuff, Later is now!
Allow getSLURL for experiences
WIP Experience list menu
Also make EXPERIENCE > OBJECT, because mainline started OBJECT already
[XPTools] Add Experience support to Name UI
[XPTools] Fix experience profile UI 9c3067e843265587e91c659200a8d783acf2d9b2
[XPTools] Fix experience location showing "last" and getting set to "last"
[XPTools] Move Experiences floater from view menu to world menu
[XPTools] Fix up more UI
[XPTools] Fix experiences panels
[XPTools] Hide pieces of the Experiences menu when they're not usable
[XPTools] More UI work, mostly to get the menus working
[XPTools] The events list is for events, not experiences, remove menu

# Conflicts:
#	indra/llcommon/llsd.cpp - merge with unstable branch
#	indra/llmessage/message_prehash.cpp
#	indra/llmessage/message_prehash.h
#	indra/llui/llscrollbar.cpp
#	indra/llui/llscrollcontainer.cpp
#	indra/llui/llurlentry.cpp
#	indra/llui/llurlregistry.cpp
#	indra/newview/app_settings/keywords.ini
#	indra/newview/app_settings/settings.xml
#	indra/newview/llappviewer.cpp
#	indra/newview/llappviewer.h
#	indra/newview/llassetuploadresponders.cpp
#	indra/newview/llcompilequeue.* - merge stable
#	indra/newview/llfloaterabout.cpp
#	indra/newview/llfloaterland.* - merge unstable
#	indra/newview/llfloaterproperties.cpp
#	indra/newview/llfloaterregioninfo.* - merge unstable
#	indra/newview/llmenucommands.cpp - merge unstable
#	indra/newview/llpreviewscript.cpp - merge unstable
#	indra/newview/llviewermessage.cpp - merge unstable
#	indra/newview/llviewerregion.cpp - merge unstable
#	indra/newview/skins/default/textures/textures.xml - merge unstable
#	indra/newview/skins/default/xui/en-us/strings.xml - merge unstable
2020-02-04 21:18:47 -05:00
Liru Færs
9a53824d6d Move click_for_profile into LLNameUI base for use in nameboxes
This allows having a linked name text on profiles without it stealing mouse
2020-01-31 14:32:45 -05:00
Router Gray
a9e2672820 [Lib] Update Linux Fmod to 2.00.07 2020-01-22 01:40:52 -06:00
Router Gray
138cf5d4f8 [AIS] Apparently friending a class isn't friendly enough. 2020-01-22 01:38:40 -06:00
402 changed files with 22690 additions and 11543 deletions

View File

@@ -8,7 +8,7 @@ name = "pypi"
[packages]
llbase = "*"
certifi = "*"
autobuild = {hg = "https://bitbucket.org/alchemyviewer/autobuild-1.1"}
autobuild = {git = "https://git.alchemyviewer.org/alchemy/autobuild.git"}
[requires]
python_version = "2.7"

View File

@@ -410,11 +410,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>4614b29cc98021cf1770a8290171602b</string>
<string>a96fda7ad5cee967823f5c94390ba35b</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows/crashpad-ce32d093.7-windows-7.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows/crashpad-c6d76a90.194-windows-194.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -424,18 +424,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>d801461b7a6a40fffab828aa1e01e3e6</string>
<string>5ff95ca1007ed2dc300b59de17453201</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows64/crashpad-ce32d093.7-windows64-7.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/crashpad/windows64/crashpad-c6d76a90.194-windows64-194.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>ce32d093.7</string>
<string>c6d76a90.194</string>
</map>
<key>curl</key>
<map>
@@ -664,11 +664,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>06746b78827e9a0c6b666bd2528d36ad</string>
<string>695efb6fc548a56dc4ff34e8d9a37bfb</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://bitbucket.org/SingularityViewer/libraries/downloads/dullahan-1.1.1320_73.1.12%252Bgee4b49f%252Bchromium-73.0.3683.75-linux64-192030536.tar.bz2</string>
<string>https://bitbucket.org/router_gray/3p-dullahan/downloads/dullahan-1.3.202002250830_79.1.38_gecefb59_chromium-79.0.3945.130-linux64-200580406.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -678,9 +678,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>e19b664ad8cf9e7f4a7bf649d28faa76</string>
<string>1b278ff2535f428ea6536683d096fdd0</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://bitbucket.org/SingularityViewer/libraries/downloads/dullahan-1.1.1320_73.1.12+gee4b49f+chromium-73.0.3683.75-windows-191102212.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/dullahan/windows/dullahan-1.3.201911222116_78.3.7_gea7ef34_chromium-78.0.3904.108-windows-2.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -690,18 +692,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>414190fd1ce3876ee3efc682b06ae65c</string>
<string>b9346fea7643b10308c7bd9a769ef5f7</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://depot.alchemyviewer.org/pub/packages/windows64/msvc-1920/dullahan-1.1.1320_73.1.12-gee4b49f-chromium-73.0.3683.75-windows64-190871757.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/dullahan/windows64/dullahan-1.3.201911222103_78.3.7_gea7ef34_chromium-78.0.3904.108-windows64-2.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.1.1320_73.1.12+gee4b49f+chromium-73.0.3683.75</string>
<string>1.3.201911222103_78.3.7_gea7ef34_chromium-78.0.3904.108</string>
</map>
<key>elfio</key>
<map>
@@ -816,7 +818,7 @@
<key>fmodstudio</key>
<map>
<key>copyright</key>
<string>FMOD Studio, copyright (c) Firelight Technologies Pty, Ltd., 2012-2019.</string>
<string>FMOD Studio, Copyright (c) Firelight Technologies Pty Ltd.</string>
<key>description</key>
<string>FMOD Studio audio system library</string>
<key>license</key>
@@ -874,11 +876,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>54dbd41322a08a1fc333ca6d96af5502</string>
<string>ccd495598894c8e2e541a348015ee3f0</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>/opt/devel/secondlife/pkg/fmodstudio-2.00.06.3-linux64-3.tar.bz2</string>
<string>/opt/devel/fmodstudio-2.00.07.200182252-linux64-200182252.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -888,11 +890,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>22daed7c860daaef217eb8d90dfc1119</string>
<string>d32efb193ffcd73bcba4875ddfd17bf0</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.00.06.3-windows-3.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.00.07.4-windows-4.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -902,18 +904,18 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ccf7b1935743df55244139c4323c0465</string>
<string>0604fd6b53ceaf14ce04d0de1bea51b8</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.00.06.3-windows64-3.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.00.07.4-windows64-4.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.00.06.3</string>
<string>2.00.07.4</string>
</map>
<key>fonts</key>
<map>
@@ -996,7 +998,7 @@
<key>freetype</key>
<map>
<key>copyright</key>
<string>Copyright 2006-2017 by David Turner, Robert Wilhelm, and Werner Lemberg.</string>
<string>Copyright 2006-2018 by David Turner, Robert Wilhelm, and Werner Lemberg.</string>
<key>description</key>
<string>Font rendering library</string>
<key>license</key>
@@ -1931,38 +1933,6 @@
<key>version</key>
<string>7.11.1.297294</string>
</map>
<key>modernjson</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2013-2018 Niels Lohmann</string>
<key>description</key>
<string>JSON for Modern C++</string>
<key>license</key>
<string>MIT</string>
<key>license_file</key>
<string>LICENSES/modernjson.txt</string>
<key>name</key>
<string>modernjson</string>
<key>platforms</key>
<map>
<key>common</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>6f11eca7e2a6ca61f9217e949a64f026</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>https://depot.alchemyviewer.org/pub/common/lib/modernjson-3.2.0-common-201809210551.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
<string>3.2.0</string>
</map>
<key>nvapi</key>
<map>
<key>copyright</key>
@@ -2506,7 +2476,7 @@
<key>vlc-bin</key>
<map>
<key>copyright</key>
<string>Copyright (C) 1998-2016 VLC authors and VideoLAN</string>
<string>Copyright (C) 1998-2020 VLC authors and VideoLAN</string>
<key>license</key>
<string>GPL2</string>
<key>license_file</key>
@@ -2544,9 +2514,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>add560654a53cb1c554044a4fac3c718</string>
<string>3ff1d097e4f9b8f864a639aff974a506</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12144/71458/vlc_bin-2.2.8.511703-windows-511703.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/vlc-bin/windows/vlc_bin-3.0.8.189-windows-189.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -2556,16 +2526,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>94bf04b49acc1e1bf2c06e2232f8a083</string>
<string>b890b109b526cc6ad211eadefed83316</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/12145/71463/vlc_bin-2.2.8.511703-windows64-511703.tar.bz2</string>
<string>https://pkg.alchemyviewer.org/repository/autobuild-external/vlc-bin/windows64/vlc_bin-3.0.8.189-windows64-189.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>2.2.8.511703</string>
<string>3.0.8.189</string>
</map>
<key>xmlrpc-epi</key>
<map>

View File

@@ -1,13 +1,13 @@
# -*- cmake -*-
include(Prebuilt)
if (STANDALONE)
if (LINUX)
include(FindPkgConfig)
pkg_check_modules(OGG REQUIRED ogg)
pkg_check_modules(VORBIS REQUIRED vorbis)
pkg_check_modules(VORBISENC REQUIRED vorbisenc)
pkg_check_modules(VORBISFILE REQUIRED vorbisfile)
else (STANDALONE)
else (LINUX)
use_prebuilt_binary(ogg_vorbis)
set(VORBIS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
set(VORBISENC_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS})
@@ -32,7 +32,7 @@ else (STANDALONE)
set(VORBISENC_LIBRARIES vorbisenc)
set(VORBISFILE_LIBRARIES vorbisfile)
endif (WINDOWS)
endif (STANDALONE)
endif (LINUX)
link_directories(
${VORBIS_LIBRARY_DIRS}

View File

@@ -50,7 +50,6 @@ set(cmake_SOURCE_FILES
GooglePerfTools.cmake
Hunspell.cmake
JPEG.cmake
Json.cmake
LLAddBuildTest.cmake
LLAppearance.cmake
LLAudio.cmake

View File

@@ -13,10 +13,6 @@ include(LLCommon)
# set up platform specific lists of files that need to be copied
###################################################################
if(WINDOWS)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
include(InstallRequiredSystemLibrariesAL)
set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug")
set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo")
set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}/Release")
@@ -96,26 +92,6 @@ if(WINDOWS)
list(APPEND release_files fmod.dll)
endif (USE_FMODSTUDIO)
foreach(redistfullfile IN LISTS CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
get_filename_component(redistfilepath ${redistfullfile} DIRECTORY )
get_filename_component(redistfilename ${redistfullfile} NAME)
copy_if_different(
${redistfilepath}
"${SHARED_LIB_STAGING_DIR_RELEASE}"
out_targets
${redistfilename}
)
set(third_party_targets ${third_party_targets} ${out_targets})
copy_if_different(
${redistfilepath}
"${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}"
out_targets
${redistfilename}
)
set(third_party_targets ${third_party_targets} ${out_targets})
endforeach()
elseif(DARWIN)
set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug/Resources")
set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/Resources")
@@ -148,10 +124,10 @@ elseif(DARWIN)
libndofdev.dylib
)
if (FMODSTUDIO)
if (USE_FMODSTUDIO)
list(APPEND debug_files libfmodL.dylib)
list(APPEND release_files libfmod.dylib)
endif (FMODSTUDIO)
endif (USE_FMODSTUDIO)
elseif(LINUX)
# linux is weird, multiple side by side configurations aren't supported
@@ -181,12 +157,9 @@ elseif(LINUX)
set(release_files
libapr-1.so.0
libaprutil-1.so.0
libatk-1.0.so
libexpat.so
libexpat.so.1
libGLOD.so
libgmodule-2.0.so
libgobject-2.0.so
libopenal.so
)

View File

@@ -1,24 +1,11 @@
# -*- cmake -*-
include(Prebuilt)
if (STANDALONE)
if (LINUX)
include(FindPkgConfig)
pkg_check_modules(DBUSGLIB REQUIRED dbus-glib-1)
elseif (LINUX)
use_prebuilt_binary(dbus-glib)
set(DBUSGLIB_FOUND ON FORCE BOOL)
set(DBUSGLIB_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/dbus
)
# We don't need to explicitly link against dbus-glib itself, because
# the viewer probes for the system's copy at runtime.
set(DBUSGLIB_LIBRARIES
gobject-2.0
glib-2.0
)
endif (STANDALONE)
endif (LINUX)
if (DBUSGLIB_FOUND)
set(DBUSGLIB ON CACHE BOOL "Build with dbus-glib message bus support.")

View File

@@ -1,741 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
InstallRequiredSystemLibraries
------------------------------
Include this module to search for compiler-provided system runtime
libraries and add install rules for them. Some optional variables
may be set prior to including the module to adjust behavior:
``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS``
Specify additional runtime libraries that may not be detected.
After inclusion any detected libraries will be appended to this.
``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP``
Set to TRUE to skip calling the :command:`install(PROGRAMS)` command to
allow the includer to specify its own install rule, using the value of
``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS`` to get the list of libraries.
``CMAKE_INSTALL_DEBUG_LIBRARIES``
Set to TRUE to install the debug runtime libraries when available
with MSVC tools.
``CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY``
Set to TRUE to install only the debug runtime libraries with MSVC
tools even if the release runtime libraries are also available.
``CMAKE_INSTALL_UCRT_LIBRARIES``
Set to TRUE to install the Windows Universal CRT libraries for
app-local deployment (e.g. to Windows XP). This is meaningful
only with MSVC from Visual Studio 2015 or higher.
One may set a ``CMAKE_WINDOWS_KITS_10_DIR`` *environment variable*
to an absolute path to tell CMake to look for Windows 10 SDKs in
a custom location. The specified directory is expected to contain
``Redist/ucrt/DLLs/*`` directories.
``CMAKE_INSTALL_MFC_LIBRARIES``
Set to TRUE to install the MSVC MFC runtime libraries.
``CMAKE_INSTALL_OPENMP_LIBRARIES``
Set to TRUE to install the MSVC OpenMP runtime libraries
``CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION``
Specify the :command:`install(PROGRAMS)` command ``DESTINATION``
option. If not specified, the default is ``bin`` on Windows
and ``lib`` elsewhere.
``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS``
Set to TRUE to disable warnings about required library files that
do not exist. (For example, Visual Studio Express editions may
not provide the redistributable files.)
``CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT``
Specify the :command:`install(PROGRAMS)` command ``COMPONENT``
option. If not specified, no such option will be used.
#]=======================================================================]
cmake_policy(PUSH)
cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
set(_IRSL_HAVE_Intel FALSE)
set(_IRSL_HAVE_MSVC FALSE)
foreach(LANG IN ITEMS C CXX Fortran)
if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel")
if(NOT _IRSL_HAVE_Intel)
get_filename_component(_Intel_basedir "${CMAKE_${LANG}_COMPILER}" PATH)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_Intel_archdir intel64)
else()
set(_Intel_archdir x86)
endif()
set(_Intel_compiler_ver ${CMAKE_${LANG}_COMPILER_VERSION})
if(WIN32)
get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../redist/${_Intel_archdir}/compiler" ABSOLUTE)
elseif(APPLE)
get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../compiler/lib" ABSOLUTE)
else()
if(EXISTS "${_Intel_basedir}/../lib/${_Intel_archdir}_lin")
get_filename_component(_Intel_redistdir "${_Intel_basedir}/../lib/${_Intel_archdir}" ABSOLUTE)
else()
get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../compiler/lib/${_Intel_archdir}_lin" ABSOLUTE)
endif()
endif()
set(_IRSL_HAVE_Intel TRUE)
endif()
elseif("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "MSVC")
set(_IRSL_HAVE_MSVC TRUE)
endif()
endforeach()
if(MSVC)
file(TO_CMAKE_PATH "$ENV{SYSTEMROOT}" SYSTEMROOT)
if(CMAKE_CL_64)
if(MSVC_VERSION GREATER 1599)
# VS 10 and later:
set(CMAKE_MSVC_ARCH x64)
else()
# VS 9 and earlier:
set(CMAKE_MSVC_ARCH amd64)
endif()
else()
set(CMAKE_MSVC_ARCH x86)
endif()
get_filename_component(devenv_dir "${CMAKE_MAKE_PROGRAM}" PATH)
get_filename_component(base_dir "${devenv_dir}/../.." ABSOLUTE)
if(MSVC_VERSION EQUAL 1300)
set(__install__libs
"${SYSTEMROOT}/system32/msvcp70.dll"
"${SYSTEMROOT}/system32/msvcr70.dll"
)
endif()
if(MSVC_VERSION EQUAL 1310)
set(__install__libs
"${SYSTEMROOT}/system32/msvcp71.dll"
"${SYSTEMROOT}/system32/msvcr71.dll"
)
endif()
if(MSVC_TOOLSET_VERSION EQUAL 80)
# Find the runtime library redistribution directory.
get_filename_component(msvc_install_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]" ABSOLUTE)
if(DEFINED MSVC80_REDIST_DIR AND EXISTS "${MSVC80_REDIST_DIR}")
set(MSVC_REDIST_DIR "${MSVC80_REDIST_DIR}") # use old cache entry
endif()
find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC80.CRT/Microsoft.VC80.CRT.manifest
PATHS
"${msvc_install_dir}/../../VC/redist"
"${base_dir}/VC/redist"
)
mark_as_advanced(MSVC_REDIST_DIR)
set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.CRT")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs
"${MSVC_CRT_DIR}/Microsoft.VC80.CRT.manifest"
"${MSVC_CRT_DIR}/msvcm80.dll"
"${MSVC_CRT_DIR}/msvcp80.dll"
"${MSVC_CRT_DIR}/msvcr80.dll"
)
else()
set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_CRT_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC80.DebugCRT")
set(__install__libs ${__install__libs}
"${MSVC_CRT_DIR}/Microsoft.VC80.DebugCRT.manifest"
"${MSVC_CRT_DIR}/msvcm80d.dll"
"${MSVC_CRT_DIR}/msvcp80d.dll"
"${MSVC_CRT_DIR}/msvcr80d.dll"
)
endif()
endif()
if(MSVC_TOOLSET_VERSION EQUAL 90)
# Find the runtime library redistribution directory.
get_filename_component(msvc_install_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]" ABSOLUTE)
get_filename_component(msvc_express_install_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\9.0;InstallDir]" ABSOLUTE)
if(DEFINED MSVC90_REDIST_DIR AND EXISTS "${MSVC90_REDIST_DIR}")
set(MSVC_REDIST_DIR "${MSVC90_REDIST_DIR}") # use old cache entry
endif()
find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest
PATHS
"${msvc_install_dir}/../../VC/redist"
"${msvc_express_install_dir}/../../VC/redist"
"${base_dir}/VC/redist"
)
mark_as_advanced(MSVC_REDIST_DIR)
set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.CRT")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs
"${MSVC_CRT_DIR}/Microsoft.VC90.CRT.manifest"
"${MSVC_CRT_DIR}/msvcm90.dll"
"${MSVC_CRT_DIR}/msvcp90.dll"
"${MSVC_CRT_DIR}/msvcr90.dll"
)
else()
set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_CRT_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC90.DebugCRT")
set(__install__libs ${__install__libs}
"${MSVC_CRT_DIR}/Microsoft.VC90.DebugCRT.manifest"
"${MSVC_CRT_DIR}/msvcm90d.dll"
"${MSVC_CRT_DIR}/msvcp90d.dll"
"${MSVC_CRT_DIR}/msvcr90d.dll"
)
endif()
endif()
set(MSVC_REDIST_NAME "")
set(_MSVC_DLL_VERSION "")
set(_MSVC_IDE_VERSION "")
if(MSVC_VERSION GREATER_EQUAL 2000)
message(WARNING "MSVC ${MSVC_VERSION} not yet supported.")
elseif(MSVC_VERSION_VERSION GREATER_EQUAL 143)
message(WARNING "MSVC toolset v${MSVC_VERSION_VERSION} not yet supported.")
elseif(MSVC_TOOLSET_VERSION EQUAL 142)
set(MSVC_REDIST_NAME VC142)
set(_MSVC_DLL_VERSION 140)
set(_MSVC_IDE_VERSION 16)
if(MSVC_VERSION EQUAL 1920)
# VS2019 named this differently prior to update 1.
set(MSVC_REDIST_NAME VC141)
endif()
elseif(MSVC_TOOLSET_VERSION EQUAL 141)
set(MSVC_REDIST_NAME VC141)
set(_MSVC_DLL_VERSION 140)
set(_MSVC_IDE_VERSION 15)
if(MSVC_VERSION EQUAL 1910)
# VS2017 named this differently prior to update 3.
set(MSVC_REDIST_NAME VC150)
endif()
elseif(MSVC_TOOLSET_VERSION)
set(MSVC_REDIST_NAME VC${MSVC_TOOLSET_VERSION})
math(EXPR _MSVC_DLL_VERSION "${MSVC_TOOLSET_VERSION} / 10 * 10")
math(EXPR _MSVC_IDE_VERSION "${MSVC_TOOLSET_VERSION} / 10")
endif()
set(_MSVCRT_DLL_VERSION "")
set(_MSVCRT_IDE_VERSION "")
if(_MSVC_IDE_VERSION GREATER_EQUAL 10)
set(_MSVCRT_DLL_VERSION "${_MSVC_DLL_VERSION}")
set(_MSVCRT_IDE_VERSION "${_MSVC_IDE_VERSION}")
endif()
if(_MSVCRT_DLL_VERSION)
set(v "${_MSVCRT_DLL_VERSION}")
set(vs "${_MSVCRT_IDE_VERSION}")
# Find the runtime library redistribution directory.
if(vs VERSION_LESS 15 AND DEFINED MSVC${vs}_REDIST_DIR AND EXISTS "${MSVC${vs}_REDIST_DIR}")
set(MSVC_REDIST_DIR "${MSVC${vs}_REDIST_DIR}") # use old cache entry
endif()
if(NOT vs VERSION_LESS 15)
set(_vs_redist_paths "")
cmake_host_system_information(RESULT _vs_dir QUERY VS_${vs}_DIR) # undocumented query
if(IS_DIRECTORY "${_vs_dir}")
file(GLOB _vs_redist_paths "${_vs_dir}/VC/Redist/MSVC/*")
endif()
unset(_vs_dir)
else()
get_filename_component(_vs_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${vs}.0;InstallDir]" ABSOLUTE)
set(programfilesx86 "ProgramFiles(x86)")
set(_vs_redist_paths
"${_vs_dir}/../../VC/redist"
"${base_dir}/VC/redist"
"$ENV{ProgramFiles}/Microsoft Visual Studio ${vs}.0/VC/redist"
"$ENV{${programfilesx86}}/Microsoft Visual Studio ${vs}.0/VC/redist"
)
unset(_vs_dir)
unset(programfilesx86)
endif()
find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.CRT PATHS ${_vs_redist_paths})
unset(_vs_redist_paths)
mark_as_advanced(MSVC_REDIST_DIR)
set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.CRT")
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs
"${MSVC_CRT_DIR}/msvcp${v}.dll"
)
if(NOT vs VERSION_LESS 14)
file(GLOB __msvcr_dlls "${MSVC_CRT_DIR}/*.dll")
list(APPEND __install__libs ${__msvcr_dlls})
else()
list(APPEND __install__libs "${MSVC_CRT_DIR}/msvcr${v}.dll")
endif()
else()
set(__install__libs)
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_CRT_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.DebugCRT")
set(__install__libs ${__install__libs}
"${MSVC_CRT_DIR}/msvcp${v}d.dll"
)
if(NOT vs VERSION_LESS 14)
list(APPEND __install__libs
"${MSVC_CRT_DIR}/vcruntime${v}d.dll"
"${MSVC_CRT_DIR}/concrt${v}d.dll"
)
else()
list(APPEND __install__libs "${MSVC_CRT_DIR}/msvcr${v}d.dll")
endif()
endif()
if(CMAKE_INSTALL_UCRT_LIBRARIES AND NOT vs VERSION_LESS 14)
# Find the Windows Kits directory.
get_filename_component(windows_kits_dir
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" ABSOLUTE)
set(programfilesx86 "ProgramFiles(x86)")
if(";${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION};$ENV{UCRTVersion};$ENV{WindowsSDKVersion};" MATCHES [=[;(10\.[0-9.]+)[;\]]=])
set(__ucrt_version "${CMAKE_MATCH_1}/")
else()
set(__ucrt_version "")
endif()
find_path(WINDOWS_KITS_DIR
NAMES
Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll
Redist/ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll
PATHS
$ENV{CMAKE_WINDOWS_KITS_10_DIR}
"${windows_kits_dir}"
"$ENV{ProgramFiles}/Windows Kits/10"
"$ENV{${programfilesx86}}/Windows Kits/10"
)
mark_as_advanced(WINDOWS_KITS_DIR)
# Glob the list of UCRT DLLs.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
if(EXISTS "${WINDOWS_KITS_DIR}/Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll")
file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/*.dll")
else()
file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/Redist/ucrt/DLLs/${CMAKE_MSVC_ARCH}/*.dll")
endif()
list(APPEND __install__libs ${__ucrt_dlls})
endif()
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
if(EXISTS "${WINDOWS_KITS_DIR}/bin/${__ucrt_version}${CMAKE_MSVC_ARCH}/ucrt/ucrtbased.dll")
file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/bin/${__ucrt_version}${CMAKE_MSVC_ARCH}/ucrt/*.dll")
else()
file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/bin/${CMAKE_MSVC_ARCH}/ucrt/*.dll")
endif()
list(APPEND __install__libs ${__ucrt_dlls})
endif()
endif()
endif()
if(CMAKE_INSTALL_MFC_LIBRARIES)
if(MSVC_VERSION EQUAL 1300)
set(__install__libs ${__install__libs}
"${SYSTEMROOT}/system32/mfc70.dll"
)
endif()
if(MSVC_VERSION EQUAL 1310)
set(__install__libs ${__install__libs}
"${SYSTEMROOT}/system32/mfc71.dll"
)
endif()
if(MSVC_VERSION EQUAL 1400)
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_MFC_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC80.DebugMFC")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/Microsoft.VC80.DebugMFC.manifest"
"${MSVC_MFC_DIR}/mfc80d.dll"
"${MSVC_MFC_DIR}/mfc80ud.dll"
"${MSVC_MFC_DIR}/mfcm80d.dll"
"${MSVC_MFC_DIR}/mfcm80ud.dll"
)
endif()
set(MSVC_MFC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.MFC")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/Microsoft.VC80.MFC.manifest"
"${MSVC_MFC_DIR}/mfc80.dll"
"${MSVC_MFC_DIR}/mfc80u.dll"
"${MSVC_MFC_DIR}/mfcm80.dll"
"${MSVC_MFC_DIR}/mfcm80u.dll"
)
endif()
# include the language dll's for vs8 as well as the actual dll's
set(MSVC_MFCLOC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.MFCLOC")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
set(__install__libs ${__install__libs}
"${MSVC_MFCLOC_DIR}/Microsoft.VC80.MFCLOC.manifest"
"${MSVC_MFCLOC_DIR}/mfc80chs.dll"
"${MSVC_MFCLOC_DIR}/mfc80cht.dll"
"${MSVC_MFCLOC_DIR}/mfc80enu.dll"
"${MSVC_MFCLOC_DIR}/mfc80esp.dll"
"${MSVC_MFCLOC_DIR}/mfc80deu.dll"
"${MSVC_MFCLOC_DIR}/mfc80fra.dll"
"${MSVC_MFCLOC_DIR}/mfc80ita.dll"
"${MSVC_MFCLOC_DIR}/mfc80jpn.dll"
"${MSVC_MFCLOC_DIR}/mfc80kor.dll"
)
endif()
if(MSVC_VERSION EQUAL 1500)
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_MFC_DIR
"${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC90.DebugMFC")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/Microsoft.VC90.DebugMFC.manifest"
"${MSVC_MFC_DIR}/mfc90d.dll"
"${MSVC_MFC_DIR}/mfc90ud.dll"
"${MSVC_MFC_DIR}/mfcm90d.dll"
"${MSVC_MFC_DIR}/mfcm90ud.dll"
)
endif()
set(MSVC_MFC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.MFC")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/Microsoft.VC90.MFC.manifest"
"${MSVC_MFC_DIR}/mfc90.dll"
"${MSVC_MFC_DIR}/mfc90u.dll"
"${MSVC_MFC_DIR}/mfcm90.dll"
"${MSVC_MFC_DIR}/mfcm90u.dll"
)
endif()
# include the language dll's for vs9 as well as the actual dll's
set(MSVC_MFCLOC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.MFCLOC")
# Install the manifest that allows DLLs to be loaded from the
# directory containing the executable.
set(__install__libs ${__install__libs}
"${MSVC_MFCLOC_DIR}/Microsoft.VC90.MFCLOC.manifest"
"${MSVC_MFCLOC_DIR}/mfc90chs.dll"
"${MSVC_MFCLOC_DIR}/mfc90cht.dll"
"${MSVC_MFCLOC_DIR}/mfc90enu.dll"
"${MSVC_MFCLOC_DIR}/mfc90esp.dll"
"${MSVC_MFCLOC_DIR}/mfc90deu.dll"
"${MSVC_MFCLOC_DIR}/mfc90fra.dll"
"${MSVC_MFCLOC_DIR}/mfc90ita.dll"
"${MSVC_MFCLOC_DIR}/mfc90jpn.dll"
"${MSVC_MFCLOC_DIR}/mfc90kor.dll"
)
endif()
set(_MFC_DLL_VERSION "")
set(_MFC_IDE_VERSION "")
if(_MSVC_IDE_VERSION GREATER_EQUAL 10)
set(_MFC_DLL_VERSION ${_MSVC_DLL_VERSION})
set(_MFC_IDE_VERSION ${_MSVC_IDE_VERSION})
endif()
if(_MFC_DLL_VERSION)
set(v "${_MFC_DLL_VERSION}")
set(vs "${_MFC_IDE_VERSION}")
# Starting with VS 15 the MFC DLLs may be in a different directory.
if (NOT vs VERSION_LESS 15)
file(GLOB _MSVC_REDIST_DIRS "${MSVC_REDIST_DIR}/../*")
find_path(MSVC_REDIST_MFC_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFC
PATHS ${_MSVC_REDIST_DIRS} NO_DEFAULT_PATH)
mark_as_advanced(MSVC_REDIST_MFC_DIR)
unset(_MSVC_REDIST_DIRS)
else()
set(MSVC_REDIST_MFC_DIR "${MSVC_REDIST_DIR}")
endif()
# Multi-Byte Character Set versions of MFC are available as optional
# addon since Visual Studio 12. So for version 12 or higher, check
# whether they are available and exclude them if they are not.
if(CMAKE_INSTALL_DEBUG_LIBRARIES)
set(MSVC_MFC_DIR
"${MSVC_REDIST_MFC_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.DebugMFC")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfc${v}ud.dll"
"${MSVC_MFC_DIR}/mfcm${v}ud.dll"
)
if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}d.dll")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfc${v}d.dll"
)
endif()
if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}d.dll")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfcm${v}d.dll"
)
endif()
endif()
set(MSVC_MFC_DIR "${MSVC_REDIST_MFC_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFC")
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfc${v}u.dll"
"${MSVC_MFC_DIR}/mfcm${v}u.dll"
)
if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}.dll")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfc${v}.dll"
)
endif()
if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}.dll")
set(__install__libs ${__install__libs}
"${MSVC_MFC_DIR}/mfcm${v}.dll"
)
endif()
endif()
# include the language dll's as well as the actual dll's
set(MSVC_MFCLOC_DIR "${MSVC_REDIST_MFC_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFCLOC")
set(__install__libs ${__install__libs}
"${MSVC_MFCLOC_DIR}/mfc${v}chs.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}cht.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}deu.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}enu.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}esn.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}fra.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}ita.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}jpn.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}kor.dll"
"${MSVC_MFCLOC_DIR}/mfc${v}rus.dll"
)
endif()
endif()
# MSVC 8 was the first version with OpenMP
# Furthermore, there is no debug version of this
if(CMAKE_INSTALL_OPENMP_LIBRARIES AND _IRSL_HAVE_MSVC)
set(_MSOMP_DLL_VERSION ${_MSVC_DLL_VERSION})
set(_MSOMP_IDE_VERSION ${_MSVC_IDE_VERSION})
if(_MSOMP_DLL_VERSION)
set(v "${_MSOMP_DLL_VERSION}")
set(vs "${_MSOMP_IDE_VERSION}")
set(MSVC_OPENMP_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.OPENMP")
if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
set(__install__libs ${__install__libs}
"${MSVC_OPENMP_DIR}/vcomp${v}.dll")
endif()
endif()
endif()
foreach(lib
${__install__libs}
)
if(EXISTS ${lib})
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib})
else()
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
message(WARNING "system runtime library file does not exist: '${lib}'")
# This warning indicates an incomplete Visual Studio installation
# or a bug somewhere above here in this file.
# If you would like to avoid this warning, fix the real problem, or
# set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including
# this file.
endif()
endif()
endforeach()
endif()
if(_IRSL_HAVE_Intel)
unset(__install_libs)
if(CMAKE_INSTALL_OPENMP_LIBRARIES)
if(WIN32)
list(APPEND __install_libs "${_Intel_redistdir}/libiomp5md.dll" "${_Intel_redistdir}/libiompstubs5md.dll")
elseif(APPLE)
list(APPEND __install_libs "${_Intel_redistdir}/libiomp5.dylib" "${_Intel_redistdir}/libiompstubs5.dylib")
else()
list(APPEND __install_libs "${_Intel_redistdir}/libiomp5.so" "${_Intel_redistdir}/libiompstubs5.so")
if(_Intel_compiler_ver VERSION_LESS 17)
list(APPEND __install_libs "${_Intel_redistdir}/libomp_db.so")
endif()
if(_Intel_compiler_ver VERSION_LESS 13)
list(APPEND __install_libs "${_Intel_redistdir}/libiompprof5.so")
endif()
endif()
endif()
if(WIN32)
set(__install_dirs "${_Intel_redistdir}/1033")
if(EXISTS "${_Intel_redistdir}/1041")
list(APPEND __install_dirs "${_Intel_redistdir}/1041")
endif()
if(_Intel_compiler_ver VERSION_LESS 18)
list(APPEND __install_dirs "${_Intel_redistdir}/irml" "${_Intel_redistdir}/irml_c")
endif()
foreach(__Intel_lib IN ITEMS cilkrts20.dll libchkp.dll libioffload_host.dll libirngmd.dll
libmmd.dll libmmdd.dll libmpx.dll liboffload.dll svml_dispmd.dll)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel)
list(APPEND __install_libs "${_Intel_redistdir}/libgfxoffload.dll")
endif()
if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
foreach(__Intel_lib IN ITEMS ifdlg100.dll libicaf.dll libifcoremd.dll libifcoremdd.dll libifcorert.dll libifcorertd.dll libifportmd.dll)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
elseif(APPLE)
foreach(__Intel_lib IN ITEMS libchkp.dylib libcilkrts.5.dylib libcilkrts.dylib libimf.dylib libintlc.dylib libirc.dylib libirng.dylib libsvml.dylib)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel)
if(_Intel_compiler_ver VERSION_LESS 17)
list(APPEND __install_libs "${_Intel_redistdir}/libistrconv.dylib")
endif()
endif()
if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
foreach(__Intel_lib IN ITEMS libifcore.dylib libifcoremt.dylib libifport.dylib libifportmt.dylib)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
else()
foreach(__Intel_lib IN ITEMS libchkp.so libcilkrts.so libcilkrts.so.5 libimf.so libintlc.so libintlc.so.5 libirc.so libpdbx.so libpdbx.so.5 libsvml.so)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
if(_Intel_compiler_ver VERSION_GREATER_EQUAL 13)
foreach(__Intel_lib IN ITEMS libirng.so liboffload.so liboffload.so.5)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel)
set(__install_dirs "${_Intel_redistdir}/irml")
list(APPEND __install_libs "${_Intel_redistdir}/cilk_db.so")
if(_Intel_compiler_ver VERSION_GREATER_EQUAL 15)
list(APPEND __install_libs "${_Intel_redistdir}/libistrconv.so" "${_Intel_redistdir}/libgfxoffload.so")
endif()
endif()
if(_Intel_compiler_ver VERSION_GREATER_EQUAL 16)
foreach(__Intel_lib IN ITEMS libioffload_host.so libioffload_host.so.5 libioffload_target.so libioffload_target.so.5 libmpx.so offload_main)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
if(_Intel_compiler_ver VERSION_LESS 15)
foreach(__Intel_lib IN ITEMS libcxaguard.so libcxaguard.so.5)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
foreach(__Intel_lib IN ITEMS libicaf.so libifcore.so libifcore.so.5 libifcoremt.so libifcoremt.so.5 libifport.so libifport.so.5)
list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}")
endforeach()
endif()
endif()
foreach(lib IN LISTS __install_libs)
if(EXISTS ${lib})
list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${lib})
else()
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
message(WARNING "system runtime library file does not exist: '${lib}'")
endif()
endif()
endforeach()
foreach(dir IN LISTS __install_dirs)
if(EXISTS ${dir})
list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_DIRECTORIES ${dir})
else()
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
message(WARNING "system runtime library file does not exist: '${dir}'")
endif()
endif()
endforeach()
endif()
if(WATCOM)
get_filename_component( CompilerPath ${CMAKE_C_COMPILER} PATH )
if(CMAKE_C_COMPILER_VERSION)
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
else()
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
endif()
string(REGEX MATCHALL "[0-9]+" _watcom_version_list "${_compiler_version}")
list(GET _watcom_version_list 0 _watcom_major)
list(GET _watcom_version_list 1 _watcom_minor)
set( __install__libs
${CompilerPath}/clbr${_watcom_major}${_watcom_minor}.dll
${CompilerPath}/mt7r${_watcom_major}${_watcom_minor}.dll
${CompilerPath}/plbr${_watcom_major}${_watcom_minor}.dll )
foreach(lib
${__install__libs}
)
if(EXISTS ${lib})
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib})
else()
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
message(WARNING "system runtime library file does not exist: '${lib}'")
# This warning indicates an incomplete Watcom installation
# or a bug somewhere above here in this file.
# If you would like to avoid this warning, fix the real problem, or
# set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including
# this file.
endif()
endif()
endforeach()
endif()
# Include system runtime libraries in the installation if any are
# specified by CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS.
if(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP)
if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION)
if(WIN32)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION bin)
else()
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION lib)
endif()
endif()
if(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT)
set(_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT
COMPONENT ${CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT})
endif()
install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION}
${_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT}
)
install(DIRECTORY ${CMAKE_INSTALL_SYSTEM_RUNTIME_DIRECTORIES}
DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION}
${_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT}
)
endif()
endif()
cmake_policy(POP)

View File

@@ -7,6 +7,6 @@ set(LLAUDIO_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llaudio
)
add_definitions(-DOV_EXCLUDE_STATIC_CALLBACKS)
#add_definitions(-DOV_EXCLUDE_STATIC_CALLBACKS)
set(LLAUDIO_LIBRARIES llaudio ${OPENAL_LIBRARIES})

View File

@@ -1,11 +1,9 @@
# -*- cmake -*-
include(Prebuilt)
include(FreeType)
if (STANDALONE)
if (LINUX)
include(FindPkgConfig)
if (LINUX)
set(PKGCONFIG_PACKAGES
atk
cairo
@@ -21,8 +19,8 @@ if (STANDALONE)
pangox
pangoxft
sdl
x11
)
endif (LINUX)
foreach(pkg ${PKGCONFIG_PACKAGES})
pkg_check_modules(${pkg} REQUIRED ${pkg})
@@ -31,39 +29,6 @@ if (STANDALONE)
list(APPEND UI_LIBRARIES ${${pkg}_LIBRARIES})
add_definitions(${${pkg}_CFLAGS_OTHERS})
endforeach(pkg)
else (STANDALONE)
if (LINUX)
use_prebuilt_binary(gtk-atk-pango-glib)
set(UI_LIBRARIES
atk-1.0
cairo
gdk-x11-2.0
gdk_pixbuf-2.0
Xinerama
glib-2.0
gio-2.0
gmodule-2.0
gobject-2.0
gthread-2.0
gtk-x11-2.0
pango-1.0
pangoft2-1.0
pangoxft-1.0
pangocairo-1.0
pixman-1
X11
${FREETYPE_LIBRARIES}
)
endif (LINUX)
include_directories (
${LIBS_PREBUILT_DIR}/include
)
foreach(include ${${LL_ARCH}_INCLUDES})
include_directories(${LIBS_PREBUILT_DIR}/include/${include})
endforeach(include)
endif (STANDALONE)
if (LINUX)
add_definitions(-DLL_GTK=1 -DLL_X11=1)
endif (LINUX)

View File

@@ -270,6 +270,8 @@ if (NOT VIEWER_CHANNEL_GRK)
set(VIEWER_CHANNEL_GRK "\\u03B1") # "α"
elseif (VIEWER_CHANNEL_TYPE MATCHES "Beta")
set(VIEWER_CHANNEL_GRK "\\u03B2") # "β"
else()
set(VIEWER_CHANNEL_GRK "")
endif ()
endif (NOT VIEWER_CHANNEL_GRK)

View File

@@ -15,10 +15,15 @@ FetchContent_Declare(
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 6.1.2
)
FetchContent_Declare(
nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.7.3
)
FetchContent_Declare(
absl
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
GIT_TAG 29235139149790f5afc430c11cec8f1eb1677607
GIT_TAG 0033c9ea91a52ade7c6b725aa2ef3cbe15463421
)
# This is a hack because absl has dumb cmake
@@ -44,5 +49,14 @@ if(WINDOWS)
FetchContent_MakeAvailable(fmt)
endif()
# Typically you don't care so much for a third party library's tests to be
# run from your own project's code.
set(JSON_BuildTests OFF CACHE INTERNAL "")
# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
set(JSON_Install OFF CACHE INTERNAL "")
FetchContent_MakeAvailable(nlohmann_json)
unset(CMAKE_FOLDER)
unset(CMAKE_POSITION_INDEPENDENT_CODE)

View File

@@ -12,7 +12,6 @@ include(Linking)
include(Boost)
include(OpenSSL)
include(LLSharedLibs)
include(Json)
include(Copy3rdPartyLibs)
include(ZLIB)
include(URIPARSER)
@@ -300,6 +299,7 @@ target_link_libraries(
${Boost_SYSTEM_LIBRARY}
${CORESERVICES_LIBRARY}
${URIPARSER_LIBRARY}
nlohmann_json::nlohmann_json
${RT_LIBRARY}
)

View File

@@ -132,7 +132,7 @@ class LL_COMMON_API AIArgs
// Add another replacement.
AIArgs& operator()(char const* key, std::string const& replacement) { mArgs[key] = replacement; return *this; }
// The destructor may not throw.
~AIArgs() throw() { }
~AIArgs() noexcept { }
// Accessor.
LLStringUtil::format_map_t const& operator*() const { return mArgs; }
@@ -193,7 +193,7 @@ class LL_COMMON_API Line
Line(std::string const& xml_desc, AIArgs const& args, bool newline = false) : mNewline(newline), mXmlDesc(xml_desc), mArgs(args), mType(normal) { }
Line(Prefix const& prefix, bool newline = false) : mNewline(newline), mXmlDesc("AIPrefix"), mArgs("[PREFIX]", prefix.str()), mType(prefix.type()) { }
// The destructor may not throw.
~Line() throw() { }
~Line() noexcept { }
// Prepend a newline before this line.
void set_newline(void) { mNewline = true; }
@@ -225,7 +225,7 @@ class LL_COMMON_API Error : public std::exception
typedef std::deque<Line> lines_type;
// The destructor may not throw.
~Error() throw() { }
~Error() noexcept { }
// Accessors.
lines_type const& lines(void) const { return mLines; }
@@ -267,7 +267,7 @@ class LL_COMMON_API ErrorCode : public Error
public:
// The destructor may not throw.
~ErrorCode() throw() { }
~ErrorCode() noexcept { }
// Accessor.
int getCode(void) const { return mCode; }

View File

@@ -244,7 +244,6 @@ const U8 SIM_ACCESS_DOWN = 254;
const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
// attachment constants
const U32 MAX_AGENT_ATTACHMENTS = 38;
const U8 ATTACHMENT_ADD = 0x80;
// god levels

View File

@@ -353,8 +353,14 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// NEW Macros for debugging, allow the passing of a string tag
#ifdef SHOW_DEBUG
#define DO_DEBUG_LOG
#else
#define DO_DEBUG_LOG if (false)
#endif
// Pass comma separated list of tags (currently only supports up to 0, 1, or 2)
#define LL_DEBUGS(...) lllog(LLError::LEVEL_DEBUG, false, false, ##__VA_ARGS__)
#define LL_DEBUGS(...) DO_DEBUG_LOG lllog(LLError::LEVEL_DEBUG, false, false, ##__VA_ARGS__)
#define LL_INFOS(...) lllog(LLError::LEVEL_INFO, false, false, ##__VA_ARGS__)
#define LL_WARNS(...) lllog(LLError::LEVEL_WARN, false, false, ##__VA_ARGS__)
#define LL_ERRS(...) lllog(LLError::LEVEL_ERROR, false, false, ##__VA_ARGS__)
@@ -363,12 +369,12 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
// Only print the log message once (good for warnings or infos that would otherwise
// spam the log file over and over, such as tighter loops).
#define LL_DEBUGS_ONCE(...) lllog(LLError::LEVEL_DEBUG, true, false, ##__VA_ARGS__)
#define LL_DEBUGS_ONCE(...) DO_DEBUG_LOG lllog(LLError::LEVEL_DEBUG, true, false, ##__VA_ARGS__)
#define LL_INFOS_ONCE(...) lllog(LLError::LEVEL_INFO, true, false, ##__VA_ARGS__)
#define LL_WARNS_ONCE(...) lllog(LLError::LEVEL_WARN, true, false, ##__VA_ARGS__)
// No function name
#define LL_DEBUGS_NF(...) lllog(LLError::LEVEL_DEBUG, false, true, ##__VA_ARGS__)
#define LL_DEBUGS_NF(...) DO_DEBUG_LOG {lllog(LLError::LEVEL_DEBUG, false, true, ##__VA_ARGS__)
#define LL_INFOS_NF(...) lllog(LLError::LEVEL_INFO, false, true, ##__VA_ARGS__)
#define LL_WARNS_NF(...) lllog(LLError::LEVEL_WARN, false, true, ##__VA_ARGS__)
#define LL_ERRS_NF(...) lllog(LLError::LEVEL_ERROR, false, true, ##__VA_ARGS__)

View File

@@ -412,7 +412,7 @@ public:
std::runtime_error(what),
mData(data)
{}
virtual ~LLErrorEvent() throw() {}
virtual ~LLErrorEvent() noexcept {}
LLSD getData() const { return mData; }

View File

@@ -381,10 +381,9 @@ std::string LLSDArgsMapper::formatlist(const LLSD& list)
{
std::ostringstream out;
const char* delim = "";
for (LLSD::array_const_iterator li(list.beginArray()), lend(list.endArray());
li != lend; ++li)
for (auto const& entry : list.array())
{
out << delim << li->asString();
out << delim << entry.asString();
delim = ", ";
}
return out.str();
@@ -494,10 +493,9 @@ struct LLEventDispatcher::MapParamsDispatchEntry: public LLEventDispatcher::Para
{
// Build the set of all param keys, then delete the ones that are
// optional. What's left are the ones that are required.
for (LLSD::array_const_iterator pi(params.beginArray()), pend(params.endArray());
pi != pend; ++pi)
for (auto const& entry : params.array())
{
mRequired[pi->asString()] = LLSD();
mRequired[entry.asString()] = LLSD();
}
if (defaults.isArray() || defaults.isUndefined())

View File

@@ -182,10 +182,10 @@ public:
bool operator! () const { return ! mListener; }
/// explicit accessor
const LLEventListener& getListener() const { return *mListener; }
const ::LLEventListener& getListener() const { return *mListener; }
/// implicit conversion to LLEventListener
operator LLEventListener() const { return *mListener; }
operator ::LLEventListener() const { return *mListener; }
/// allow calling directly
bool operator()(const LLSD& event) const;
@@ -277,7 +277,7 @@ namespace LLEventDetail
/// Any callable capable of connecting an LLEventListener to an
/// LLStandardSignal to produce an LLBoundListener can be mapped to this
/// signature.
typedef boost::function<LLBoundListener(const LLEventListener&)> ConnectFunc;
typedef boost::function<LLBoundListener(const ::LLEventListener&)> ConnectFunc;
/// overload of visit_and_connect() when we have a string identifier available
template <typename LISTENER>
@@ -547,7 +547,7 @@ private:
virtual void reset();
private:
virtual LLBoundListener listen_impl(const std::string& name, const LLEventListener&,
virtual LLBoundListener listen_impl(const std::string& name, const ::LLEventListener&,
const NameList& after,
const NameList& before);
std::string mName;
@@ -845,7 +845,7 @@ namespace LLEventDetail
* Visitor binds a reference to LLEventListener so we can track() any
* shared_ptrs we find in the argument list.
*/
Visitor(LLEventListener& listener):
Visitor(::LLEventListener& listener):
mListener(listener)
{
}
@@ -988,7 +988,7 @@ namespace LLEventDetail
|*==========================================================================*/
/// Bind a reference to the LLEventListener to call its track() method.
LLEventListener& mListener;
::LLEventListener& mListener;
};
/**
@@ -1005,7 +1005,7 @@ namespace LLEventDetail
const ConnectFunc& connect_func)
{
// Capture the listener
LLEventListener listener(raw_listener);
::LLEventListener listener(raw_listener);
// Define our Visitor, binding the listener so we can call
// listener.track() if we discover any shared_ptr<Foo>.
LLEventDetail::Visitor visitor(listener);

View File

@@ -54,6 +54,7 @@ std::string LLFile::strerr(int errn)
{
char buffer[256];
strerror_s(buffer, errn); // infers sizeof(buffer) -- love it!
buffer[255] = 0;
return buffer;
}

View File

@@ -126,9 +126,9 @@ public:
virtual Date asDate() const { return LLDate(); }
virtual URI asURI() const { return LLURI(); }
virtual const Binary& asBinary() const { static const std::vector<U8> empty; return empty; }
virtual const String& asStringRef() const { static const std::string empty; return empty; }
virtual const String& asStringRef() const { static const std::string empty; return empty; }
virtual bool has(const String&) const { return false; }
virtual LLSD get(const String&) const { return LLSD(); }
virtual LLSD getKeys() const { return LLSD::emptyArray(); }
@@ -140,10 +140,14 @@ public:
virtual void erase(Integer) { }
virtual const LLSD& ref(Integer) const { return undef(); }
virtual LLSD::map_const_iterator beginMap() const { return endMap(); }
virtual LLSD::map_const_iterator endMap() const { static const std::map<String, LLSD> empty; return empty.end(); }
virtual LLSD::array_const_iterator beginArray() const { return endArray(); }
virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); }
virtual const std::map<String, LLSD>& map() const { static const std::map<String, LLSD> empty; return empty; }
virtual std::map<String, LLSD>& map() { static std::map<String, LLSD> empty; return empty; }
LLSD::map_const_iterator beginMap() const { return map().begin(); }
LLSD::map_const_iterator endMap() const { return map().end(); }
virtual const std::vector<LLSD>& array() const { static const std::vector<LLSD> empty; return empty; }
virtual std::vector<LLSD>& array() { static std::vector<LLSD> empty; return empty; }
LLSD::array_const_iterator beginArray() const { return array().begin(); }
LLSD::array_const_iterator endArray() const { return array().end(); }
virtual void dumpStats() const;
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
@@ -183,10 +187,11 @@ namespace
public:
ImplBase(DataRef value) : mValue(value) { }
virtual LLSD::Type type() const { return T; }
LLSD::Type type() const override { return T; }
using LLSD::Impl::assign; // Unhiding base class virtuals...
virtual void assign(LLSD::Impl*& var, DataRef value) {
void assign(LLSD::Impl*& var, DataRef value) override
{
if (shared())
{
Impl::assign(var, value);
@@ -199,16 +204,16 @@ namespace
};
class ImplBoolean
class ImplBoolean final
: public ImplBase<LLSD::TypeBoolean, LLSD::Boolean>
{
public:
ImplBoolean(LLSD::Boolean v) : Base(v) { }
virtual LLSD::Boolean asBoolean() const { return mValue; }
virtual LLSD::Integer asInteger() const { return mValue ? 1 : 0; }
virtual LLSD::Real asReal() const { return mValue ? 1 : 0; }
virtual LLSD::String asString() const;
LLSD::Boolean asBoolean() const override { return mValue; }
LLSD::Integer asInteger() const override { return mValue ? 1 : 0; }
LLSD::Real asReal() const override { return mValue ? 1 : 0; }
LLSD::String asString() const override;
};
LLSD::String ImplBoolean::asString() const
@@ -220,32 +225,32 @@ namespace
{ return mValue ? "true" : ""; }
class ImplInteger
class ImplInteger final
: public ImplBase<LLSD::TypeInteger, LLSD::Integer>
{
public:
ImplInteger(LLSD::Integer v) : Base(v) { }
virtual LLSD::Boolean asBoolean() const { return mValue != 0; }
virtual LLSD::Integer asInteger() const { return mValue; }
virtual LLSD::Real asReal() const { return mValue; }
virtual LLSD::String asString() const;
LLSD::Boolean asBoolean() const override { return mValue != 0; }
LLSD::Integer asInteger() const override { return mValue; }
LLSD::Real asReal() const override { return mValue; }
LLSD::String asString() const override;
};
LLSD::String ImplInteger::asString() const
{ return llformat("%d", mValue); }
class ImplReal
class ImplReal final
: public ImplBase<LLSD::TypeReal, LLSD::Real>
{
public:
ImplReal(LLSD::Real v) : Base(v) { }
virtual LLSD::Boolean asBoolean() const;
virtual LLSD::Integer asInteger() const;
virtual LLSD::Real asReal() const { return mValue; }
virtual LLSD::String asString() const;
LLSD::Boolean asBoolean() const override;
LLSD::Integer asInteger() const override;
LLSD::Real asReal() const override { return mValue; }
LLSD::String asString() const override;
};
LLSD::Boolean ImplReal::asBoolean() const
@@ -258,21 +263,21 @@ namespace
{ return llformat("%lg", mValue); }
class ImplString
class ImplString final
: public ImplBase<LLSD::TypeString, LLSD::String, const LLSD::String&>
{
public:
ImplString(const LLSD::String& v) : Base(v) { }
virtual LLSD::Boolean asBoolean() const { return !mValue.empty(); }
virtual LLSD::Integer asInteger() const;
virtual LLSD::Real asReal() const;
virtual LLSD::String asString() const { return mValue; }
virtual LLSD::UUID asUUID() const { return LLUUID(mValue); }
virtual LLSD::Date asDate() const { return LLDate(mValue); }
virtual LLSD::URI asURI() const { return LLURI(mValue); }
virtual int size() const { return mValue.size(); }
virtual const LLSD::String& asStringRef() const { return mValue; }
LLSD::Boolean asBoolean() const override { return !mValue.empty(); }
LLSD::Integer asInteger() const override;
LLSD::Real asReal() const override;
LLSD::String asString() const override { return mValue; }
LLSD::UUID asUUID() const override { return LLUUID(mValue); }
LLSD::Date asDate() const override { return LLDate(mValue); }
LLSD::URI asURI() const override { return LLURI(mValue); }
int size() const override { return mValue.size(); }
const LLSD::String& asStringRef() const override { return mValue; }
};
LLSD::Integer ImplString::asInteger() const
@@ -302,18 +307,18 @@ namespace
}
class ImplUUID
class ImplUUID final
: public ImplBase<LLSD::TypeUUID, LLSD::UUID, const LLSD::UUID&>
{
public:
ImplUUID(const LLSD::UUID& v) : Base(v) { }
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::UUID asUUID() const { return mValue; }
LLSD::String asString() const override { return mValue.asString(); }
LLSD::UUID asUUID() const override { return mValue; }
};
class ImplDate
class ImplDate final
: public ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>
{
public:
@@ -321,41 +326,42 @@ namespace
: ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>(v)
{ }
virtual LLSD::Integer asInteger() const
LLSD::Integer asInteger() const override
{
return (LLSD::Integer)(mValue.secondsSinceEpoch());
}
virtual LLSD::Real asReal() const
LLSD::Real asReal() const override
{
return mValue.secondsSinceEpoch();
}
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::Date asDate() const { return mValue; }
LLSD::String asString() const override { return mValue.asString(); }
LLSD::Date asDate() const override { return mValue; }
};
class ImplURI
class ImplURI final
: public ImplBase<LLSD::TypeURI, LLSD::URI, const LLSD::URI&>
{
public:
ImplURI(const LLSD::URI& v) : Base(v) { }
virtual LLSD::String asString() const{ return mValue.asString(); }
virtual LLSD::URI asURI() const { return mValue; }
LLSD::String asString() const override { return mValue.asString(); }
LLSD::URI asURI() const override { return mValue; }
};
class ImplBinary
class ImplBinary final
: public ImplBase<LLSD::TypeBinary, LLSD::Binary, const LLSD::Binary&>
{
public:
ImplBinary(const LLSD::Binary& v) : Base(v) { }
virtual const LLSD::Binary& asBinary() const{ return mValue; }
const LLSD::Binary& asBinary() const override { return mValue; }
};
class ImplMap : public LLSD::Impl
class ImplMap final : public LLSD::Impl
{
private:
typedef std::map<LLSD::String, LLSD> DataMap;
@@ -368,33 +374,31 @@ namespace
public:
ImplMap() { }
virtual ImplMap& makeMap(LLSD::Impl*&);
ImplMap& makeMap(LLSD::Impl*&) override;
virtual LLSD::Type type() const { return LLSD::TypeMap; }
LLSD::Type type() const override { return LLSD::TypeMap; }
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
LLSD::Boolean asBoolean() const override { return !mData.empty(); }
virtual bool has(const LLSD::String&) const;
bool has(const LLSD::String&) const override;
using LLSD::Impl::get; // Unhiding get(LLSD::Integer)
using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer)
using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer)
virtual LLSD get(const LLSD::String&) const;
virtual LLSD getKeys() const;
LLSD get(const LLSD::String&) const override;
LLSD getKeys() const override;
void insert(const LLSD::String& k, const LLSD& v);
virtual void erase(const LLSD::String&);
void erase(const LLSD::String&) override;
LLSD& ref(const LLSD::String&);
virtual const LLSD& ref(const LLSD::String&) const;
const LLSD& ref(const LLSD::String&) const override;
virtual int size() const { return mData.size(); }
int size() const override { return mData.size(); }
LLSD::map_iterator beginMap() { return mData.begin(); }
LLSD::map_iterator endMap() { return mData.end(); }
virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
DataMap& map() final override { return mData; }
const DataMap& map() const final override { return mData; }
virtual void dumpStats() const;
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
void dumpStats() const override;
void calcStats(S32 type_counts[], S32 share_counts[]) const override;
};
ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
@@ -481,7 +485,7 @@ namespace
{
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
Impl::calcStats((*iter).second, type_counts, share_counts);
iter++;
++iter;
}
// Add in the values for this map
@@ -489,7 +493,7 @@ namespace
}
class ImplArray : public LLSD::Impl
class ImplArray final : public LLSD::Impl
{
private:
typedef std::vector<LLSD> DataVector;
@@ -502,32 +506,28 @@ namespace
public:
ImplArray() { }
virtual ImplArray& makeArray(Impl*&);
ImplArray& makeArray(Impl*&) override;
virtual LLSD::Type type() const { return LLSD::TypeArray; }
LLSD::Type type() const override { return LLSD::TypeArray; }
virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
LLSD::Boolean asBoolean() const override { return !mData.empty(); }
using LLSD::Impl::get; // Unhiding get(LLSD::String)
using LLSD::Impl::erase; // Unhiding erase(LLSD::String)
using LLSD::Impl::ref; // Unhiding ref(LLSD::String)
virtual int size() const;
virtual LLSD get(LLSD::Integer) const;
int size() const override;
LLSD get(LLSD::Integer) const override;
void set(LLSD::Integer, const LLSD&);
void insert(LLSD::Integer, const LLSD&);
LLSD& append(const LLSD&);
virtual void erase(LLSD::Integer);
void erase(LLSD::Integer) override;
LLSD& ref(LLSD::Integer);
virtual const LLSD& ref(LLSD::Integer) const;
const LLSD& ref(LLSD::Integer) const override;
LLSD::array_iterator beginArray() { return mData.begin(); }
LLSD::array_iterator endArray() { return mData.end(); }
LLSD::reverse_array_iterator rbeginArray() { return mData.rbegin(); }
LLSD::reverse_array_iterator rendArray() { return mData.rend(); }
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
DataVector& array() final override { return mData; }
const DataVector& array() const final override { return mData; }
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
void calcStats(S32 type_counts[], S32 share_counts[]) const override;
};
ImplArray& ImplArray::makeArray(Impl*& var)
@@ -631,7 +631,7 @@ namespace
while (iter != endArray())
{ // Add values for all items held in the array
Impl::calcStats((*iter), type_counts, share_counts);
iter++;
++iter;
}
// Add in the values for this array
@@ -703,7 +703,7 @@ void LLSD::Impl::assign(Impl*& var, const Impl* other)
void LLSD::Impl::assignUndefined(Impl*& var)
{
reset(var, 0);
reset(var, nullptr);
}
void LLSD::Impl::assign(Impl*& var, LLSD::Boolean v)
@@ -779,7 +779,7 @@ void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const
S32 tp = S32(type());
if (0 <= tp && tp < LLSD::TypeLLSDNumTypes)
{
type_counts[tp]++;
type_counts[tp]++;
if (shared())
{
share_counts[tp]++;
@@ -813,10 +813,10 @@ namespace
}
LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; }
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); }
LLSD::LLSD() : impl(nullptr) { ALLOC_LLSD_OBJECT; }
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, nullptr); }
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
LLSD::LLSD(const LLSD& other) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(other); }
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
@@ -825,17 +825,17 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
LLSD::Type LLSD::type() const { return safe(impl).type(); }
// Scalar Constructors
LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Boolean v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Integer v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Real v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const UUID& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const String& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Date& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const URI& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Binary& v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
// Convenience Constructors
LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); }
LLSD::LLSD(F32 v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign((Real)v); }
// Scalar Assignment
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
@@ -860,7 +860,7 @@ const LLSD::Binary& LLSD::asBinary() const { return safe(impl).asBinary(); }
const LLSD::String& LLSD::asStringRef() const { return safe(impl).asStringRef(); }
// const char * helpers
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const char* v) : impl(nullptr) { ALLOC_LLSD_OBJECT; assign(v); }
void LLSD::assign(const char* v)
{
if(v) assign(std::string(v));
@@ -927,7 +927,7 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
// sStorage will point to the result of the last call. This will actually
// be one leak, but since this is used only when running under the
// debugger, it should not be an issue.
static char *sStorage = NULL;
static char *sStorage = nullptr;
delete[] sStorage;
std::string out_string;
{
@@ -938,7 +938,7 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
out << LLSDNotationStreamer(llsd);
out_string = out.str();
}
int len = out_string.length();
size_t len = out_string.length();
sStorage = new char[len + 1];
memcpy(sStorage, out_string.c_str(), len);
sStorage[len] = '\0';
@@ -957,18 +957,24 @@ const char *LLSD::dump(const LLSD &llsd)
return llsd_dump(llsd, false);
}
LLSD::map_iterator LLSD::beginMap() { return makeMap(impl).beginMap(); }
LLSD::map_iterator LLSD::endMap() { return makeMap(impl).endMap(); }
LLSD::map_const_iterator LLSD::beginMap() const { return safe(impl).beginMap(); }
LLSD::map_const_iterator LLSD::endMap() const { return safe(impl).endMap(); }
std::map<LLSD::String, LLSD>& LLSD::map() { return makeMap(impl).map(); }
const std::map<LLSD::String, LLSD>& LLSD::map() const { return safe(impl).map(); }
LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray(); }
LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); }
LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); }
LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); }
LLSD::map_iterator LLSD::beginMap() { return map().begin(); }
LLSD::map_iterator LLSD::endMap() { return map().end(); }
LLSD::map_const_iterator LLSD::beginMap() const { return map().cbegin(); }
LLSD::map_const_iterator LLSD::endMap() const { return map().cend(); }
LLSD::reverse_array_iterator LLSD::rbeginArray() { return makeArray(impl).rbeginArray(); }
LLSD::reverse_array_iterator LLSD::rendArray() { return makeArray(impl).rendArray(); }
std::vector<LLSD>& LLSD::array() { return makeArray(impl).array(); }
const std::vector<LLSD>& LLSD::array() const { return safe(impl).array(); }
LLSD::array_iterator LLSD::beginArray() { return array().begin(); }
LLSD::array_iterator LLSD::endArray() { return array().end(); }
LLSD::array_const_iterator LLSD::beginArray() const{ return array().cbegin(); }
LLSD::array_const_iterator LLSD::endArray() const { return array().cend(); }
LLSD::reverse_array_iterator LLSD::rbeginArray() { return array().rbegin(); }
LLSD::reverse_array_iterator LLSD::rendArray() { return array().rend(); }
namespace llsd
{

View File

@@ -320,6 +320,8 @@ public:
typedef std::map<String, LLSD>::iterator map_iterator;
typedef std::map<String, LLSD>::const_iterator map_const_iterator;
std::map<String, LLSD>& map();
const std::map<String, LLSD>& map() const;
map_iterator beginMap();
map_iterator endMap();
map_const_iterator beginMap() const;
@@ -329,6 +331,8 @@ public:
typedef std::vector<LLSD>::const_iterator array_const_iterator;
typedef std::vector<LLSD>::reverse_iterator reverse_array_iterator;
std::vector<LLSD>& array();
const std::vector<LLSD>& array() const;
array_iterator beginArray();
array_iterator endArray();
array_const_iterator beginArray() const;

View File

@@ -122,9 +122,9 @@ nlohmann::json LlsdToJson(const LLSD &val)
}
break;
case LLSD::TypeArray:
for (LLSD::array_const_iterator it = val.beginArray(); it != val.endArray(); ++it)
for (auto const& entry : val.array())
{
result.push_back(LlsdToJson(*it));
result.push_back(LlsdToJson(entry));
}
break;
case LLSD::TypeBinary:

View File

@@ -267,12 +267,10 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI
}
else if (sd.isArray())
{
for (LLSD::array_const_iterator it = sd.beginArray();
it != sd.endArray();
++it)
for (auto const& entry : sd.array())
{
stack.push_back(make_pair(std::string(), true));
readSDValues(cb, *it, stack);
readSDValues(cb, entry, stack);
stack.pop_back();
}
}

View File

@@ -1322,13 +1322,11 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32
{
ostr << post << pre << "[";
bool need_comma = false;
auto iter = data.beginArray();
auto end = data.endArray();
for(; iter != end; ++iter)
for (const auto& entry : data.array())
{
if(need_comma) ostr << ",";
if (need_comma) ostr << ",";
need_comma = true;
format_count += format_impl(*iter, ostr, options, level + 1);
format_count += format_impl(entry, ostr, options, level + 1);
}
ostr << "]";
break;
@@ -1461,11 +1459,9 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
ostr.put('[');
U32 size_nbo = htonl(data.size());
ostr.write(reinterpret_cast<const char*>(&size_nbo), sizeof(U32));
auto iter = data.beginArray();
auto end = data.endArray();
for(; iter != end; ++iter)
for (const auto& entry : data.array())
{
format_count += format(*iter, ostr);
format_count += format(entry, ostr);
}
ostr.put(']');
break;

View File

@@ -116,11 +116,9 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 opti
else
{
ostr << pre << "<array>" << post;
LLSD::array_const_iterator iter = data.beginArray();
LLSD::array_const_iterator end = data.endArray();
for(; iter != end; ++iter)
for (const auto& entry : data.array())
{
format_count += format_impl(*iter, ostr, options, level + 1);
format_count += format_impl(entry, ostr, options, level + 1);
}
ostr << pre << "</array>" << post;
}

View File

@@ -891,9 +891,9 @@ LLSD llsd_clone(LLSD value, LLSD filter)
break;
case LLSD::TypeArray:
clone = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
for (auto const& entry : value.array())
{
clone.append(llsd_clone(*ita, filter));
clone.append(llsd_clone(entry, filter));
}
break;
@@ -943,9 +943,9 @@ LLSD llsd_shallow(LLSD value, LLSD filter)
else if (value.isArray())
{
shallow = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
for (auto const& entry : value.array())
{
shallow.append(*ita);
shallow.append(entry);
}
}
else

View File

@@ -1340,7 +1340,8 @@ void LLStringUtil::formatNumber(std::string& numStr, std::string decimals)
// std::locale() throws if the locale is unknown! (EXT-7926)
try
{
strStream.imbue(std::locale(sLocale.c_str()));
std::locale locale(sLocale.c_str());
strStream.imbue(locale);
} catch (const std::exception &)
{
LL_WARNS_ONCE("Locale") << "Cannot set locale to " << sLocale << LL_ENDL;

View File

@@ -243,7 +243,7 @@ public:
bool operator<(const LLFormatMapString& rhs) const { return mString < rhs.mString; }
std::size_t length() const { return mString.length(); }
// The destructor may not throw.
~LLFormatMapString() throw() { }
~LLFormatMapString() noexcept { }
private:
std::string mString;

View File

@@ -1274,7 +1274,7 @@ BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
const S32 UNCOMPRESS_BUFFER_SIZE = 32768;
BOOL retval = FALSE;
gzFile src = NULL;
U8 buffer[UNCOMPRESS_BUFFER_SIZE];
std::array<U8, UNCOMPRESS_BUFFER_SIZE> buffer;
LLFILE *dst = NULL;
S32 bytes = 0;
tmpfile = dstfile + ".t";
@@ -1288,8 +1288,8 @@ BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
if (! dst) goto err;
do
{
bytes = gzread(src, buffer, UNCOMPRESS_BUFFER_SIZE);
size_t nwrit = fwrite(buffer, sizeof(U8), bytes, dst);
bytes = gzread(src, buffer.data(), buffer.size());
size_t nwrit = fwrite(buffer.data(), sizeof(U8), bytes, dst);
if (nwrit < (size_t) bytes)
{
LL_WARNS() << "Short write on " << tmpfile << ": Wrote " << nwrit << " of " << bytes << " bytes." << LL_ENDL;
@@ -1311,7 +1311,7 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
const S32 COMPRESS_BUFFER_SIZE = 32768;
std::string tmpfile;
BOOL retval = FALSE;
U8 buffer[COMPRESS_BUFFER_SIZE];
std::array<U8, COMPRESS_BUFFER_SIZE> buffer;
gzFile dst = NULL;
LLFILE *src = NULL;
S32 bytes = 0;
@@ -1325,9 +1325,9 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */
if (! src) goto err;
while ((bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE, src)) > 0)
while ((bytes = (S32)fread(buffer.data(), sizeof(U8), buffer.size(), src)) > 0)
{
if (gzwrite(dst, buffer, bytes) <= 0)
if (gzwrite(dst, buffer.data(), bytes) <= 0)
{
LL_WARNS() << "gzwrite failed: " << gzerror(dst, NULL) << LL_ENDL;
goto err;

View File

@@ -17,7 +17,6 @@ include_directories(
set(llinventory_SOURCE_FILES
llcategory.cpp
lleconomy.cpp
llfoldertype.cpp
llinventory.cpp
llinventorydefines.cpp
@@ -40,7 +39,6 @@ set(llinventory_HEADER_FILES
CMakeLists.txt
llcategory.h
lleconomy.h
llfoldertype.h
llinventory.h
llinventorydefines.h

View File

@@ -1,288 +0,0 @@
/**
* @file lleconomy.cpp
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
*/
#include "linden_common.h"
#include "lleconomy.h"
#include "llerror.h"
#include "message.h"
#include "v3math.h"
LLGlobalEconomy::LLGlobalEconomy()
: mObjectCount( -1 ),
mObjectCapacity( -1 ),
mPriceObjectClaim( -1 ),
mPricePublicObjectDecay( -1 ),
mPricePublicObjectDelete( -1 ),
mPriceEnergyUnit( -1 ),
mPriceUpload( -1 ),
mPriceRentLight( -1 ),
mTeleportMinPrice( -1 ),
mTeleportPriceExponent( -1 ),
mPriceGroupCreate( -1 )
{ }
LLGlobalEconomy::~LLGlobalEconomy()
{ }
void LLGlobalEconomy::addObserver(LLEconomyObserver* observer)
{
mObservers.push_back(observer);
}
void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer)
{
std::list<LLEconomyObserver*>::iterator it =
std::find(mObservers.begin(), mObservers.end(), observer);
if (it != mObservers.end())
{
mObservers.erase(it);
}
}
void LLGlobalEconomy::notifyObservers()
{
for (std::list<LLEconomyObserver*>::iterator it = mObservers.begin();
it != mObservers.end();
++it)
{
(*it)->onEconomyDataChange();
}
}
// static
void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data)
{
S32 i;
F32 f;
msg->getS32Fast(_PREHASH_Info, _PREHASH_ObjectCapacity, i);
econ_data->setObjectCapacity(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_ObjectCount, i);
econ_data->setObjectCount(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceEnergyUnit, i);
econ_data->setPriceEnergyUnit(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceObjectClaim, i);
econ_data->setPriceObjectClaim(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PricePublicObjectDecay, i);
econ_data->setPricePublicObjectDecay(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PricePublicObjectDelete, i);
econ_data->setPricePublicObjectDelete(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceUpload, i);
econ_data->setPriceUpload(i);
#if LL_LINUX
// We can optionally fake the received upload price for testing.
// Note that the server is within its rights to not obey our fake
// price. :)
const char* fakeprice_str = getenv("LL_FAKE_UPLOAD_PRICE");
if (fakeprice_str)
{
S32 fakeprice = (S32)atoi(fakeprice_str);
LL_WARNS() << "LL_FAKE_UPLOAD_PRICE: Faking upload price as L$" << fakeprice << LL_ENDL;
econ_data->setPriceUpload(fakeprice);
}
#endif
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceRentLight, i);
econ_data->setPriceRentLight(i);
msg->getS32Fast(_PREHASH_Info, _PREHASH_TeleportMinPrice, i);
econ_data->setTeleportMinPrice(i);
msg->getF32Fast(_PREHASH_Info, _PREHASH_TeleportPriceExponent, f);
econ_data->setTeleportPriceExponent(f);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceGroupCreate, i);
econ_data->setPriceGroupCreate(i);
econ_data->notifyObservers();
}
S32 LLGlobalEconomy::calculateTeleportCost(F32 distance) const
{
S32 min_cost = getTeleportMinPrice();
F32 exponent = getTeleportPriceExponent();
F32 divisor = 100.f * pow(3.f, exponent);
S32 cost = (U32)(distance * pow(log10(distance), exponent) / divisor);
if (cost < 0)
{
cost = 0;
}
else if (cost < min_cost)
{
cost = min_cost;
}
return cost;
}
S32 LLGlobalEconomy::calculateLightRent(const LLVector3& object_size) const
{
F32 intensity_mod = llmax(object_size.magVec(), 1.f);
return (S32)(intensity_mod * getPriceRentLight());
}
void LLGlobalEconomy::print()
{
LL_INFOS() << "Global Economy Settings: " << LL_ENDL;
LL_INFOS() << "Object Capacity: " << mObjectCapacity << LL_ENDL;
LL_INFOS() << "Object Count: " << mObjectCount << LL_ENDL;
LL_INFOS() << "Claim Price Per Object: " << mPriceObjectClaim << LL_ENDL;
LL_INFOS() << "Claim Price Per Public Object: " << mPricePublicObjectDecay << LL_ENDL;
LL_INFOS() << "Delete Price Per Public Object: " << mPricePublicObjectDelete << LL_ENDL;
LL_INFOS() << "Release Price Per Public Object: " << getPricePublicObjectRelease() << LL_ENDL;
LL_INFOS() << "Price Per Energy Unit: " << mPriceEnergyUnit << LL_ENDL;
LL_INFOS() << "Price Per Upload: " << mPriceUpload << LL_ENDL;
LL_INFOS() << "Light Base Price: " << mPriceRentLight << LL_ENDL;
LL_INFOS() << "Teleport Min Price: " << mTeleportMinPrice << LL_ENDL;
LL_INFOS() << "Teleport Price Exponent: " << mTeleportPriceExponent << LL_ENDL;
LL_INFOS() << "Price for group creation: " << mPriceGroupCreate << LL_ENDL;
}
LLRegionEconomy::LLRegionEconomy()
: LLGlobalEconomy(),
mPriceObjectRent( -1.f ),
mPriceObjectScaleFactor( -1.f ),
mEnergyEfficiency( -1.f ),
mBasePriceParcelClaimDefault(-1),
mBasePriceParcelClaimActual(-1),
mPriceParcelClaimFactor(-1.f),
mBasePriceParcelRent(-1),
mAreaOwned(-1.f),
mAreaTotal(-1.f)
{ }
LLRegionEconomy::~LLRegionEconomy()
{ }
BOOL LLRegionEconomy::hasData() const
{
return (mBasePriceParcelRent != -1);
}
// static
void LLRegionEconomy::processEconomyData(LLMessageSystem *msg, void** user_data)
{
S32 i;
F32 f;
LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data;
LLGlobalEconomy::processEconomyData(msg, this_ptr);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelClaim, i);
this_ptr->setBasePriceParcelClaimDefault(i);
msg->getF32(_PREHASH_Info, _PREHASH_PriceParcelClaimFactor, f);
this_ptr->setPriceParcelClaimFactor(f);
msg->getF32Fast(_PREHASH_Info, _PREHASH_EnergyEfficiency, f);
this_ptr->setEnergyEfficiency(f);
msg->getF32Fast(_PREHASH_Info, _PREHASH_PriceObjectRent, f);
this_ptr->setPriceObjectRent(f);
msg->getF32Fast(_PREHASH_Info, _PREHASH_PriceObjectScaleFactor, f);
this_ptr->setPriceObjectScaleFactor(f);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelRent, i);
this_ptr->setBasePriceParcelRent(i);
}
// static
void LLRegionEconomy::processEconomyDataRequest(LLMessageSystem *msg, void **user_data)
{
LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data;
if (!this_ptr->hasData())
{
LL_WARNS() << "Dropping EconomyDataRequest, because EconomyData message "
<< "has not been processed" << LL_ENDL;
}
msg->newMessageFast(_PREHASH_EconomyData);
msg->nextBlockFast(_PREHASH_Info);
msg->addS32Fast(_PREHASH_ObjectCapacity, this_ptr->getObjectCapacity());
msg->addS32Fast(_PREHASH_ObjectCount, this_ptr->getObjectCount());
msg->addS32Fast(_PREHASH_PriceEnergyUnit, this_ptr->getPriceEnergyUnit());
msg->addS32Fast(_PREHASH_PriceObjectClaim, this_ptr->getPriceObjectClaim());
msg->addS32Fast(_PREHASH_PricePublicObjectDecay, this_ptr->getPricePublicObjectDecay());
msg->addS32Fast(_PREHASH_PricePublicObjectDelete, this_ptr->getPricePublicObjectDelete());
msg->addS32Fast(_PREHASH_PriceParcelClaim, this_ptr->mBasePriceParcelClaimActual);
msg->addF32Fast(_PREHASH_PriceParcelClaimFactor, this_ptr->mPriceParcelClaimFactor);
msg->addS32Fast(_PREHASH_PriceUpload, this_ptr->getPriceUpload());
msg->addS32Fast(_PREHASH_PriceRentLight, this_ptr->getPriceRentLight());
msg->addS32Fast(_PREHASH_TeleportMinPrice, this_ptr->getTeleportMinPrice());
msg->addF32Fast(_PREHASH_TeleportPriceExponent, this_ptr->getTeleportPriceExponent());
msg->addF32Fast(_PREHASH_EnergyEfficiency, this_ptr->getEnergyEfficiency());
msg->addF32Fast(_PREHASH_PriceObjectRent, this_ptr->getPriceObjectRent());
msg->addF32Fast(_PREHASH_PriceObjectScaleFactor, this_ptr->getPriceObjectScaleFactor());
msg->addS32Fast(_PREHASH_PriceParcelRent, this_ptr->getPriceParcelRent());
msg->addS32Fast(_PREHASH_PriceGroupCreate, this_ptr->getPriceGroupCreate());
msg->sendReliable(msg->getSender());
}
S32 LLRegionEconomy::getPriceParcelClaim() const
{
//return (S32)((F32)mBasePriceParcelClaim * (mAreaTotal / (mAreaTotal - mAreaOwned)));
return (S32)((F32)mBasePriceParcelClaimActual * mPriceParcelClaimFactor);
}
S32 LLRegionEconomy::getPriceParcelRent() const
{
return mBasePriceParcelRent;
}
void LLRegionEconomy::print()
{
this->LLGlobalEconomy::print();
LL_INFOS() << "Region Economy Settings: " << LL_ENDL;
LL_INFOS() << "Land (square meters): " << mAreaTotal << LL_ENDL;
LL_INFOS() << "Owned Land (square meters): " << mAreaOwned << LL_ENDL;
LL_INFOS() << "Daily Object Rent: " << mPriceObjectRent << LL_ENDL;
LL_INFOS() << "Daily Land Rent (per meter): " << getPriceParcelRent() << LL_ENDL;
LL_INFOS() << "Energey Efficiency: " << mEnergyEfficiency << LL_ENDL;
}
void LLRegionEconomy::setBasePriceParcelClaimDefault(S32 val)
{
mBasePriceParcelClaimDefault = val;
if(mBasePriceParcelClaimActual == -1)
{
mBasePriceParcelClaimActual = val;
}
}
void LLRegionEconomy::setBasePriceParcelClaimActual(S32 val)
{
mBasePriceParcelClaimActual = val;
}
void LLRegionEconomy::setPriceParcelClaimFactor(F32 val)
{
mPriceParcelClaimFactor = val;
}
void LLRegionEconomy::setBasePriceParcelRent(S32 val)
{
mBasePriceParcelRent = val;
}

View File

@@ -1,159 +0,0 @@
/**
* @file lleconomy.h
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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 LL_LLECONOMY_H
#define LL_LLECONOMY_H
#include "llsingleton.h"
class LLMessageSystem;
class LLVector3;
/**
* Register an observer to be notified of economy data updates coming from server.
*/
class LLEconomyObserver
{
public:
virtual ~LLEconomyObserver() {}
virtual void onEconomyDataChange() = 0;
};
class LLGlobalEconomy
{
public:
LLGlobalEconomy();
virtual ~LLGlobalEconomy();
// This class defines its singleton internally as a typedef instead of inheriting from
// LLSingleton like most others because the LLRegionEconomy sub-class might also
// become a singleton and this pattern will more easily disambiguate them.
typedef LLSingleton<LLGlobalEconomy> Singleton;
void initSingleton() { }
virtual void print();
void addObserver(LLEconomyObserver* observer);
void removeObserver(LLEconomyObserver* observer);
void notifyObservers();
static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data);
S32 calculateTeleportCost(F32 distance) const;
S32 calculateLightRent(const LLVector3& object_size) const;
S32 getObjectCount() const { return mObjectCount; }
S32 getObjectCapacity() const { return mObjectCapacity; }
S32 getPriceObjectClaim() const { return mPriceObjectClaim; }
S32 getPricePublicObjectDecay() const { return mPricePublicObjectDecay; }
S32 getPricePublicObjectDelete() const { return mPricePublicObjectDelete; }
S32 getPricePublicObjectRelease() const { return mPriceObjectClaim - mPricePublicObjectDelete; }
S32 getPriceEnergyUnit() const { return mPriceEnergyUnit; }
S32 getPriceUpload() const { return mPriceUpload; }
S32 getPriceRentLight() const { return mPriceRentLight; }
S32 getTeleportMinPrice() const { return mTeleportMinPrice; }
F32 getTeleportPriceExponent() const { return mTeleportPriceExponent; }
S32 getPriceGroupCreate() const { return mPriceGroupCreate; }
void setObjectCount(S32 val) { mObjectCount = val; }
void setObjectCapacity(S32 val) { mObjectCapacity = val; }
void setPriceObjectClaim(S32 val) { mPriceObjectClaim = val; }
void setPricePublicObjectDecay(S32 val) { mPricePublicObjectDecay = val; }
void setPricePublicObjectDelete(S32 val) { mPricePublicObjectDelete = val; }
void setPriceEnergyUnit(S32 val) { mPriceEnergyUnit = val; }
void setPriceUpload(S32 val) { mPriceUpload = val; }
void setPriceRentLight(S32 val) { mPriceRentLight = val; }
void setTeleportMinPrice(S32 val) { mTeleportMinPrice = val; }
void setTeleportPriceExponent(F32 val) { mTeleportPriceExponent = val; }
void setPriceGroupCreate(S32 val) { mPriceGroupCreate = val; }
private:
S32 mObjectCount;
S32 mObjectCapacity;
S32 mPriceObjectClaim; // per primitive
S32 mPricePublicObjectDecay; // per primitive
S32 mPricePublicObjectDelete; // per primitive
S32 mPriceEnergyUnit;
S32 mPriceUpload;
S32 mPriceRentLight;
S32 mTeleportMinPrice;
F32 mTeleportPriceExponent;
S32 mPriceGroupCreate;
std::list<LLEconomyObserver*> mObservers;
};
class LLRegionEconomy : public LLGlobalEconomy
{
public:
LLRegionEconomy();
~LLRegionEconomy();
static void processEconomyData(LLMessageSystem *msg, void **user_data);
static void processEconomyDataRequest(LLMessageSystem *msg, void **user_data);
void print();
BOOL hasData() const;
F32 getPriceObjectRent() const { return mPriceObjectRent; }
F32 getPriceObjectScaleFactor() const {return mPriceObjectScaleFactor;}
F32 getEnergyEfficiency() const { return mEnergyEfficiency; }
S32 getPriceParcelClaim() const;
S32 getPriceParcelRent() const;
F32 getAreaOwned() const { return mAreaOwned; }
F32 getAreaTotal() const { return mAreaTotal; }
S32 getBasePriceParcelClaimActual() const { return mBasePriceParcelClaimActual; }
void setPriceObjectRent(F32 val) { mPriceObjectRent = val; }
void setPriceObjectScaleFactor(F32 val) { mPriceObjectScaleFactor = val; }
void setEnergyEfficiency(F32 val) { mEnergyEfficiency = val; }
void setBasePriceParcelClaimDefault(S32 val);
void setBasePriceParcelClaimActual(S32 val);
void setPriceParcelClaimFactor(F32 val);
void setBasePriceParcelRent(S32 val);
void setAreaOwned(F32 val) { mAreaOwned = val; }
void setAreaTotal(F32 val) { mAreaTotal = val; }
private:
F32 mPriceObjectRent;
F32 mPriceObjectScaleFactor;
F32 mEnergyEfficiency;
S32 mBasePriceParcelClaimDefault;
S32 mBasePriceParcelClaimActual;
F32 mPriceParcelClaimFactor;
S32 mBasePriceParcelRent;
F32 mAreaOwned;
F32 mAreaTotal;
};
#endif

View File

@@ -40,6 +40,8 @@
#include "llsdutil_math.h"
#include "message.h"
#include "u64.h"
#include "llregionflags.h"
#include <boost/range/adaptor/map.hpp>
static const F32 SOME_BIG_NUMBER = 1000.0f;
static const F32 SOME_BIG_NEG_NUMBER = -1000.0f;
@@ -742,8 +744,8 @@ void LLParcel::unpackMessage(LLMessageSystem* msg)
void LLParcel::packAccessEntries(LLMessageSystem* msg,
const std::map<LLUUID,LLAccessEntry>& list)
{
access_map_const_iterator cit = list.begin();
access_map_const_iterator end = list.end();
LLAccessEntry::map::const_iterator cit = list.begin();
LLAccessEntry::map::const_iterator end = list.end();
if (cit == end)
{
@@ -794,9 +796,28 @@ void LLParcel::unpackAccessEntries(LLMessageSystem* msg,
}
void LLParcel::unpackExperienceEntries(LLMessageSystem* msg, U32 type)
{
LLUUID id;
S32 i;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_List);
for (i = 0; i < count; i++)
{
msg->getUUIDFast(_PREHASH_List, _PREHASH_ID, id, i);
if (id.notNull())
{
mExperienceKeys[id] = type;
}
}
}
void LLParcel::expirePasses(S32 now)
{
access_map_iterator itor = mAccessList.begin();
LLAccessEntry::map::iterator itor = mAccessList.begin();
while (itor != mAccessList.end())
{
const LLAccessEntry& entry = (*itor).second;
@@ -886,7 +907,7 @@ BOOL LLParcel::addToAccessList(const LLUUID& agent_id, S32 time)
// Can't add owner to these lists
return FALSE;
}
access_map_iterator itor = mAccessList.begin();
LLAccessEntry::map::iterator itor = mAccessList.begin();
while (itor != mAccessList.end())
{
const LLAccessEntry& entry = (*itor).second;
@@ -931,7 +952,7 @@ BOOL LLParcel::addToBanList(const LLUUID& agent_id, S32 time)
return FALSE;
}
access_map_iterator itor = mBanList.begin();
LLAccessEntry::map::iterator itor = mBanList.begin();
while (itor != mBanList.end())
{
const LLAccessEntry& entry = (*itor).second;
@@ -970,7 +991,7 @@ BOOL remove_from_access_array(std::map<LLUUID,LLAccessEntry>* list,
const LLUUID& agent_id)
{
BOOL removed = FALSE;
access_map_iterator itor = list->begin();
LLAccessEntry::map::iterator itor = list->begin();
while (itor != list->end())
{
const LLAccessEntry& entry = (*itor).second;
@@ -1091,7 +1112,7 @@ void LLParcel::startSale(const LLUUID& buyer_id, BOOL is_buyer_group)
mSaleTimerExpires.start();
mSaleTimerExpires.setTimerExpirySec(U64Microseconds(DEFAULT_USEC_SALE_TIMEOUT));
mStatus = OS_LEASE_PENDING;
mClaimDate = time(NULL);
mClaimDate = time(nullptr);
setAuctionID(0);
// clear the autoreturn whenever land changes hands
setCleanOtherTime(0);
@@ -1313,3 +1334,58 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s)
// is a distinct option from "None" and "Other"
return LLParcel::C_ANY;
}
LLAccessEntry::map LLParcel::getExperienceKeysByType(U32 type) const
{
LLAccessEntry::map access;
LLAccessEntry entry;
xp_type_map_t::const_iterator it = mExperienceKeys.begin();
for(/**/; it != mExperienceKeys.end(); ++it)
{
if(it->second == type)
{
entry.mID = it->first;
access[entry.mID] = entry;
}
}
return access;
}
void LLParcel::clearExperienceKeysByType(U32 type)
{
xp_type_map_t::iterator it = mExperienceKeys.begin();
while(it != mExperienceKeys.end())
{
if(it->second == type)
{
mExperienceKeys.erase(it++);
}
else
{
++it;
}
}
}
void LLParcel::setExperienceKeyType(const LLUUID& experience_key, U32 type)
{
if (type == EXPERIENCE_KEY_TYPE_NONE)
{
mExperienceKeys.erase(experience_key);
}
else
{
if (countExperienceKeyType(type) < PARCEL_MAX_EXPERIENCE_LIST)
{
mExperienceKeys[experience_key] = type;
}
}
}
U32 LLParcel::countExperienceKeyType(U32 type)
{
return std::count_if(
boost::begin(mExperienceKeys | boost::adaptors::map_values),
boost::end(mExperienceKeys | boost::adaptors::map_values),
std::bind2nd(std::equal_to<U32>(), type));
}

View File

@@ -60,6 +60,9 @@ const S32 PARCEL_MAX_ACCESS_LIST = 300;
//for access/ban lists.
const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f;
// Maximum number of experiences
const S32 PARCEL_MAX_EXPERIENCE_LIST = 24;
// Weekly charge for listing a parcel in the directory
const S32 PARCEL_DIRECTORY_FEE = 30;
@@ -141,9 +144,11 @@ class LLSD;
class LLAccessEntry
{
public:
typedef std::map<LLUUID,LLAccessEntry> map;
LLAccessEntry()
: mID(),
mTime(0),
: mTime(0),
mFlags(0)
{}
@@ -152,8 +157,6 @@ public:
U32 mFlags; // Not used - currently should always be zero
};
typedef std::map<LLUUID,LLAccessEntry>::iterator access_map_iterator;
typedef std::map<LLUUID,LLAccessEntry>::const_iterator access_map_const_iterator;
class LLParcel
{
@@ -331,6 +334,9 @@ public:
void unpackAccessEntries(LLMessageSystem* msg,
std::map<LLUUID,LLAccessEntry>* list);
void unpackExperienceEntries(LLMessageSystem* msg, U32 type);
void setAABBMin(const LLVector3& min) { mAABBMin = min; }
void setAABBMax(const LLVector3& max) { mAABBMax = max; }
@@ -707,6 +713,17 @@ public:
std::map<LLUUID,LLAccessEntry> mTempBanList;
std::map<LLUUID,LLAccessEntry> mTempAccessList;
typedef std::map<LLUUID, U32> xp_type_map_t;
void setExperienceKeyType(const LLUUID& experience_key, U32 type);
U32 countExperienceKeyType(U32 type);
U32 getExperienceKeyType(const LLUUID& experience_key)const;
LLAccessEntry::map getExperienceKeysByType(U32 type)const;
void clearExperienceKeysByType(U32 type);
private:
xp_type_map_t mExperienceKeys;
};

View File

@@ -1,31 +1,25 @@
/**
* @file llparcelflags.h
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/
@@ -97,8 +91,10 @@ const U32 PF_DEFAULT = PF_ALLOW_FLY
| PF_USE_ESTATE_VOICE_CHAN;
// Access list flags
const U32 AL_ACCESS = (1 << 0);
const U32 AL_BAN = (1 << 1);
const U32 AL_ACCESS = (1 << 0);
const U32 AL_BAN = (1 << 1);
const U32 AL_ALLOW_EXPERIENCE = (1 << 3);
const U32 AL_BLOCK_EXPERIENCE = (1 << 4);
//const U32 AL_RENTER = (1 << 2);
// Block access return values. BA_ALLOWED is the only success case

View File

@@ -103,9 +103,9 @@ LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) cons
break;
case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
for (auto const& entry : value.array())
{
newSettings[key_name].append(*ita);
newSettings[key_name].append(entry);
}
break;
//case LLSD::TypeInteger:
@@ -137,9 +137,9 @@ LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) cons
break;
case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
for (auto const& entry : value.array())
{
newSettings[key_name].append(*ita);
newSettings[key_name].append(entry);
}
break;
//case LLSD::TypeInteger:

View File

@@ -240,16 +240,16 @@ bool LLSettingsDay::initialize(bool validate_frames)
{
mDayTracks[i].clear();
LLSD curtrack = tracks[i];
for (LLSD::array_const_iterator it = curtrack.beginArray(); it != curtrack.endArray(); ++it)
for (const auto& entry : curtrack.array())
{
LLSettingsBase::TrackPosition keyframe = LLSettingsBase::TrackPosition((*it)[SETTING_KEYKFRAME].asReal());
LLSettingsBase::TrackPosition keyframe = LLSettingsBase::TrackPosition(entry[SETTING_KEYKFRAME].asReal());
keyframe = llclamp(keyframe, 0.0f, 1.0f);
LLSettingsBase::ptr_t setting;
if ((*it).has(SETTING_KEYNAME))
if (entry.has(SETTING_KEYNAME))
{
std::string key_name = (*it)[SETTING_KEYNAME];
std::string key_name = entry[SETTING_KEYNAME];
if (i == TRACK_WATER)
{
setting = used[key_name];
@@ -469,36 +469,36 @@ namespace
S32 framecount(0);
for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track)
for (auto& entry : value.array())
{
S32 index = 0;
while (index < (*track).size())
while (index < entry.size())
{
LLSD& elem = (*track)[index];
LLSD& elem = entry[index];
++framecount;
if (index >= LLSettingsDay::FRAME_MAX)
{
(*track).erase(index);
entry.erase(index);
continue;
}
if (!elem.has(LLSettingsDay::SETTING_KEYKFRAME))
{
(*track).erase(index);
entry.erase(index);
continue;
}
if (!elem[LLSettingsDay::SETTING_KEYKFRAME].isReal())
{
(*track).erase(index);
entry.erase(index);
continue;
}
if (!elem.has(LLSettingsDay::SETTING_KEYNAME) &&
!elem.has(LLSettingsDay::SETTING_KEYID))
{
(*track).erase(index);
entry.erase(index);
continue;
}

View File

@@ -126,9 +126,12 @@ public:
// Returns true if this rotation is orthonormal with det ~= 1
inline bool isOkRotation() const;
} LL_ALIGN_POSTFIX(16);
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLMatrix3a>::value, "LLMatrix3a must be a trivial type");
static_assert(std::is_standard_layout<LLMatrix3a>::value, "LLMatrix3a must be a standard layout type");
static_assert(std::is_trivial<LLRotation>::value, "LLRotation must be a trivial type");
static_assert(std::is_standard_layout<LLRotation>::value, "LLRotation must be a standard layout type");
#endif
#endif

View File

@@ -718,6 +718,8 @@ inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m)
void matMulBoundBox(const LLMatrix4a &a, const LLVector4a *in_extents, LLVector4a *out_extents);
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLMatrix4a>::value, "LLMatrix4a must be a trivial type");
static_assert(std::is_standard_layout<LLMatrix4a>::value, "LLMatrix4a must be a standard layout type");
#endif
#endif

View File

@@ -45,6 +45,7 @@
#endif
extern U32 gOctreeMaxCapacity;
extern float gOctreeMinSize;
extern U32 gOctreeReserveCapacity;
#if LL_DEBUG
#define LL_OCTREE_PARANOIA_CHECK 0
@@ -404,7 +405,7 @@ public:
F32 size = mSize[0];
F32 p_size = size * 2.f;
return (radius <= 0.001f && size <= 0.001f) ||
return (radius <= gOctreeMinSize && size <= gOctreeMinSize) ||
(radius <= p_size && radius > size);
}
@@ -425,7 +426,7 @@ public:
}
void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChildCount == 0; }
bool isLeaf() const { return mChildCount == 0; }
U32 getElementCount() const { return mData.size(); }
bool isEmpty() const { return mData.size() == 0; }
@@ -498,7 +499,7 @@ public:
return node;
}
virtual bool insert(T* data)
bool insert(T* data) override
{
OctreeGuard::checkGuarded(this);
if (data == NULL || data->getBinIndex() != -1)
@@ -511,7 +512,7 @@ public:
//is it here?
if (isInside(data->getPositionGroup()))
{
if (((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius())) ||
if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
/*mElementCount++;
@@ -537,7 +538,7 @@ public:
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif
BaseType::insert(data);
LLOctreeNode<T>::notifyAddition(data);
return true;
}
else
@@ -566,8 +567,9 @@ public:
LLVector4a val;
val.setSub(center, getCenter());
val.setAbs(val);
S32 lt = val.lessThan(LLVector4a::getEpsilon()).getGatheredBits() & 0x7;
LLVector4a min_diff(gOctreeMinSize);
S32 lt = val.lessThan(min_diff).getGatheredBits() & 0x7;
if( lt == 0x7 )
{
@@ -593,7 +595,7 @@ public:
OctreeStats::getInstance()->realloc(old_cap,mData.capacity());
#endif
BaseType::insert(data);
LLOctreeNode<T>::notifyAddition(data);
return true;
}
@@ -616,6 +618,7 @@ public:
}
#endif
llassert(size[0] >= gOctreeMinSize*0.5f);
//make the new kid
child = new LLOctreeNode<T>(center, size, this);
addChild(child);
@@ -623,10 +626,7 @@ public:
child->insert(data);
}
}
// Singu note: now that we allow wider range in octree, discard them here
// if they fall out of range
#if 0
else
else if (parent)
{
//it's not in here, give it to the root
OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL;
@@ -639,12 +639,15 @@ public:
parent = node->getOctParent();
}
if(node != this)
{
node->insert(data);
}
node->insert(data);
}
else
{
// It's not in here, and we are root.
// LLOctreeRoot::insert() should have expanded
// root by now, something is wrong
OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL;
}
#endif
return false;
}
@@ -708,7 +711,7 @@ public:
checkAlive();
}
bool remove(T* data)
bool remove(T* data) final override
{
OctreeGuard::checkGuarded(this);
S32 i = data->getBinIndex();
@@ -849,10 +852,9 @@ public:
if (!silent)
{
for (U32 i = 0; i < this->getListenerCount(); i++)
for (auto& entry : this->mListeners)
{
oct_listener* listener = getOctListener(i);
listener->handleChildAddition(this, child);
((oct_listener*)entry.get())->handleChildAddition(this, child);
}
}
}
@@ -861,16 +863,17 @@ public:
{
OctreeGuard::checkGuarded(this);
for (U32 i = 0; i < this->getListenerCount(); i++)
oct_node* child = getChild(index);
for (auto& entry : this->mListeners)
{
oct_listener* listener = getOctListener(i);
listener->handleChildRemoval(this, getChild(index));
((oct_listener*)entry.get())->handleChildRemoval(this, child);
}
if (destroy)
{
mChild[index]->destroy();
delete mChild[index];
child->destroy();
delete child;
}
--mChildCount;
@@ -1012,7 +1015,7 @@ public:
}
// LLOctreeRoot::insert
bool insert(T* data)
bool insert(T* data) final override
{
if (data == NULL)
{
@@ -1050,10 +1053,15 @@ public:
{
LLOctreeNode<T>::insert(data);
}
else
else if (node->isInside(data->getPositionGroup()))
{
node->insert(data);
}
else
{
// calling node->insert(data) will return us to root
OCT_ERRS << "Failed to insert data at child node" << LL_ENDL;
}
}
else if (this->getChildCount() == 0)
{
@@ -1088,6 +1096,8 @@ public:
this->setSize(size2);
this->updateMinMax();
llassert(size[0] >= gOctreeMinSize);
//copy our children to a new branch
LLOctreeNode<T>* newnode = new LLOctreeNode<T>(center, size, this);

View File

@@ -104,7 +104,8 @@ private:
LL_ALIGN_16(LLVector4a mV);
} LL_ALIGN_POSTFIX(16);
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLPlane>::value, "LLPlane must be a trivial type");
static_assert(std::is_standard_layout<LLPlane>::value, "LLPlane must be a standard layout type");
#endif
#endif // LL_LLPLANE_H

View File

@@ -105,7 +105,9 @@ protected:
} LL_ALIGN_POSTFIX(16);
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLQuaternion2>::value, "LLQuaternion2 must be a trivial type");
static_assert(std::is_standard_layout<LLQuaternion2>::value, "LLQuaternion2 must be a standard layout type");
#endif
#endif

View File

@@ -44,7 +44,6 @@ public:
virtual void handleInsertion(const LLTreeNode<T>* node, T* data) = 0;
virtual void handleRemoval(const LLTreeNode<T>* node, T* data) = 0;
virtual void handleDestruction(const LLTreeNode<T>* node) = 0;
virtual void handleStateChange(const LLTreeNode<T>* node) = 0;
};
template <class T>
@@ -53,11 +52,15 @@ class LLTreeNode
public:
virtual ~LLTreeNode();
virtual bool insert(T* data);
virtual bool remove(T* data);
virtual void notifyRemoval(T* data);
virtual U32 getListenerCount() { return mListeners.size(); }
virtual LLTreeListener<T>* getListener(U32 index) const
virtual bool insert(T* data) = 0;
virtual bool remove(T* data) = 0;
bool notifyAddition(T* data);
void notifyRemoval(T* data);
U32 getListenerCount() const
{
return mListeners.size();
}
LLTreeListener<T>* getListener(U32 index) const
{
if(index < mListeners.size())
{
@@ -65,7 +68,10 @@ public:
}
return NULL;
}
virtual void addListener(LLTreeListener<T>* listener) { mListeners.push_back(listener); }
void addListener(LLTreeListener<T>* listener)
{
mListeners.push_back(listener);
}
protected:
void destroyListeners()
@@ -97,7 +103,7 @@ LLTreeNode<T>::~LLTreeNode()
};
template <class T>
bool LLTreeNode<T>::insert(T* data)
bool LLTreeNode<T>::notifyAddition(T* data)
{
for (U32 i = 0; i < mListeners.size(); i++)
{
@@ -106,12 +112,6 @@ bool LLTreeNode<T>::insert(T* data)
return true;
};
template <class T>
bool LLTreeNode<T>::remove(T* data)
{
return true;
};
template <class T>
void LLTreeNode<T>::notifyRemoval(T* data)
{

View File

@@ -350,6 +350,8 @@ inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v)
return s;
}
#if !defined(LL_DEBUG)
static_assert(std::is_trivial<LLVector4a>::value, "LLVector4a must be a be a trivial type");
static_assert(std::is_standard_layout<LLVector4a>::value, "LLVector4a must be a standard layout type");
#endif
#endif

View File

@@ -38,7 +38,7 @@ class LLVolumeParams;
class LLProfile;
class LLPath;
template <class T> class LLOctreeNode;
template <class T> class LLOctreeRoot;
class LLVolumeFace;
class LLVolume;
@@ -964,7 +964,7 @@ public:
// vertices per joint.
LLJointRiggingInfoTab mJointRiggingInfoTab;
LLOctreeNode<LLVolumeTriangle>* mOctree;
LLOctreeRoot<LLVolumeTriangle>* mOctree;
//whether or not face has been cache optimized
BOOL mOptimized;

View File

@@ -112,14 +112,13 @@ public:
}
//LISTENER FUNCTIONS
virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
LLOctreeNode<LLVolumeTriangle>* child);
virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { }
virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent,
const LLOctreeNode<LLVolumeTriangle>* child) { }
virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) { }
void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
LLOctreeNode<LLVolumeTriangle>* child) final override;
void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent,
const LLOctreeNode<LLVolumeTriangle>* child) final override { }
void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) final override { }
void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) final override { }
void handleDestruction(const LLTreeNode<LLVolumeTriangle>* node) final override { }
public:

View File

@@ -45,6 +45,7 @@ set(llmessage_SOURCE_FILES
llclassifiedflags.cpp
lldatapacker.cpp
lldispatcher.cpp
llexperiencecache.cpp
llfiltersd2xmlrpc.cpp
llhost.cpp
llhttpclient.cpp
@@ -133,11 +134,13 @@ set(llmessage_HEADER_FILES
llcipher.h
llcircuit.h
llclassifiedflags.h
llcororesponder.h
llcurl.h
lldatapacker.h
lldbstrings.h
lldispatcher.h
lleventflags.h
llexperiencecache.h
llfiltersd2xmlrpc.h
llfollowcamparams.h
llhost.h

View File

@@ -960,4 +960,5 @@ P(webProfileResponders);
P(wholeModelFeeResponder);
P(wholeModelUploadResponder);
P2(XMLRPCResponder, connect_40s);
P(getUpdateInfoResponder);
P(getUpdateInfoResponder);
P2(AISAPIResponder, connect_60s);

View File

@@ -335,7 +335,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
while(!sAskQueue.empty())
{
it = sAskQueue.begin();
const LLUUID& agent_id = *it;
const LLUUID agent_id = *it;
sAskQueue.erase(it);
if (url.empty())

View File

@@ -262,6 +262,8 @@ LLCacheName::~LLCacheName()
delete &impl;
}
const ReverseCache& LLCacheName::getReverseMap() const { return impl.mReverseCache; }
LLCacheName::Impl::Impl(LLMessageSystem* msg)
: mMsg(msg), mUpstreamHost(LLHost::invalid)
{

View File

@@ -57,6 +57,8 @@ public:
LLCacheName(LLMessageSystem* msg, const LLHost& upstream_host);
~LLCacheName();
const std::map<std::string, LLUUID>& getReverseMap() const;
// registers the upstream host
// for viewers, this is the currently connected simulator
// for simulators, this is the data server

View File

@@ -0,0 +1,63 @@
/**
* @file llcororesponder.h
* @brief A responder purposed to call coro functions, to ease transition to LLCoro
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
*
* Copyright (C) 2020, Liru Færs
*
* 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$
*/
#include <functional>
#include "llhttpclient.h"
struct LLCoroResponderBase : public LLHTTPClient::ResponderWithCompleted
{
const AIHTTPReceivedHeaders& getHeaders() const { return mReceivedHeaders; }
const LLSD& getContent() const { return mContent; }
char const* getName() const override final { return "LLCoroResponder"; }
protected:
LLCoroResponderBase() {}
};
struct LLCoroResponder final : public LLCoroResponderBase
{
typedef std::function<void(const LLCoroResponder&)> cb_t;
LLCoroResponder(const cb_t& cb) : mCB(cb) {}
void httpCompleted() override { mCB(*this); }
private:
const cb_t mCB;
};
struct LLCoroResponderRaw final : public LLCoroResponderBase
{
typedef std::function<void(const LLCoroResponderRaw&, const std::string&)> cb_t;
LLCoroResponderRaw(const cb_t& cb) : mCB(cb) {}
void completedRaw(const LLChannelDescriptors& channels, const buffer_ptr_t& buffer) override
{
std::string content;
decode_raw_body(channels, buffer, content);
mCB(*this, content);
}
private:
const cb_t mCB;
};

View File

@@ -0,0 +1,921 @@
/**
* @file llexperiencecache.cpp
* @brief llexperiencecache and related class definitions
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012, 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$
*/
#include "llexperiencecache.h"
#include "llavatarname.h"
#include "llcororesponder.h"
#include "llsdserialize.h"
#include "lleventfilter.h"
#include "lldir.h"
#include <set>
#include <map>
#include <boost/tokenizer.hpp>
#include <boost/concept_check.hpp>
#include <boost/smart_ptr/make_shared.hpp>
//=========================================================================
namespace LLExperienceCacheImpl
{
void mapKeys(const LLSD& legacyKeys);
F64 getErrorRetryDeltaTime(S32 status, const AIHTTPReceivedHeaders& headers);
bool maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age);
static const std::string PRIVATE_KEY = "private_id";
static const std::string EXPERIENCE_ID = "public_id";
static const std::string MAX_AGE("max-age");
static const boost::char_separator<char> EQUALS_SEPARATOR("=");
static const boost::char_separator<char> COMMA_SEPARATOR(",");
// *TODO$: this seems to be tied to mapKeys which is used by bootstrap.... but I don't think that bootstrap is used.
typedef std::map<LLUUID, LLUUID> KeyMap;
KeyMap privateToPublicKeyMap;
}
//=========================================================================
const std::string LLExperienceCache::PRIVATE_KEY = "private_id";
const std::string LLExperienceCache::MISSING = "DoesNotExist";
const std::string LLExperienceCache::AGENT_ID = "agent_id";
const std::string LLExperienceCache::GROUP_ID = "group_id";
const std::string LLExperienceCache::EXPERIENCE_ID = "public_id";
const std::string LLExperienceCache::NAME = "name";
const std::string LLExperienceCache::PROPERTIES = "properties";
const std::string LLExperienceCache::EXPIRES = "expiration";
const std::string LLExperienceCache::DESCRIPTION = "description";
const std::string LLExperienceCache::QUOTA = "quota";
const std::string LLExperienceCache::MATURITY = "maturity";
const std::string LLExperienceCache::METADATA = "extended_metadata";
const std::string LLExperienceCache::SLURL = "slurl";
// should be in sync with experience-api/experiences/models.py
const int LLExperienceCache::PROPERTY_INVALID = 1 << 0;
const int LLExperienceCache::PROPERTY_PRIVILEGED = 1 << 3;
const int LLExperienceCache::PROPERTY_GRID = 1 << 4;
const int LLExperienceCache::PROPERTY_PRIVATE = 1 << 5;
const int LLExperienceCache::PROPERTY_DISABLED = 1 << 6;
const int LLExperienceCache::PROPERTY_SUSPENDED = 1 << 7;
// default values
const F64 LLExperienceCache::DEFAULT_EXPIRATION = 600.0;
const S32 LLExperienceCache::DEFAULT_QUOTA = 128; // this is megabytes
const int LLExperienceCache::SEARCH_PAGE_SIZE = 30;
//=========================================================================
LLExperienceCache::LLExperienceCache():
mShutdown(false)
{
}
LLExperienceCache::~LLExperienceCache()
{
}
void LLExperienceCache::initSingleton()
{
mCacheFileName = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "experience_cache.xml");
LL_INFOS("ExperienceCache") << "Loading " << mCacheFileName << LL_ENDL;
llifstream cache_stream(mCacheFileName.c_str());
if (cache_stream.is_open())
{
cache_stream >> (*this);
}
}
void LLExperienceCache::cleanup()
{
LL_INFOS("ExperienceCache") << "Saving " << mCacheFileName << LL_ENDL;
llofstream cache_stream(mCacheFileName.c_str());
if (cache_stream.is_open())
{
cache_stream << (*this);
}
mShutdown = true;
}
//-------------------------------------------------------------------------
void LLExperienceCache::importFile(std::istream& istr)
{
LLSD data;
S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
if (parse_count < 1) return;
LLSD experiences = data["experiences"];
LLUUID public_key;
for (const auto& it : experiences.map())
{
public_key.set(it.first);
mCache[public_key] = it.second;
}
LL_DEBUGS("ExperienceCache") << "importFile() loaded " << mCache.size() << LL_ENDL;
}
void LLExperienceCache::exportFile(std::ostream& ostr) const
{
LLSD experiences;
cache_t::const_iterator it = mCache.begin();
for (; it != mCache.end(); ++it)
{
if (!it->second.has(EXPERIENCE_ID) || it->second[EXPERIENCE_ID].asUUID().isNull() ||
it->second.has("DoesNotExist") || (it->second.has(PROPERTIES) && it->second[PROPERTIES].asInteger() & PROPERTY_INVALID))
continue;
experiences[it->first.asString()] = it->second;
}
LLSD data;
data["experiences"] = experiences;
LLSDSerialize::toPrettyXML(data, ostr);
}
// *TODO$: Rider: This method does not seem to be used... it may be useful in testing.
void LLExperienceCache::bootstrap(const LLSD& legacyKeys, int initialExpiration)
{
LLExperienceCacheImpl::mapKeys(legacyKeys);
for (auto experience : legacyKeys.array())
{
if (experience.has(EXPERIENCE_ID))
{
if (!experience.has(EXPIRES))
{
experience[EXPIRES] = initialExpiration;
}
processExperience(experience[EXPERIENCE_ID].asUUID(), experience);
}
else
{
LL_WARNS("ExperienceCache")
<< "Skipping bootstrap entry which is missing " << EXPERIENCE_ID
<< LL_ENDL;
}
}
}
LLUUID LLExperienceCache::getExperienceId(const LLUUID& private_key, bool null_if_not_found)
{
if (private_key.isNull())
return LLUUID::null;
LLExperienceCacheImpl::KeyMap::const_iterator it = LLExperienceCacheImpl::privateToPublicKeyMap.find(private_key);
if (it == LLExperienceCacheImpl::privateToPublicKeyMap.end())
{
if (null_if_not_found)
{
return LLUUID::null;
}
return private_key;
}
LL_WARNS("LLExperience") << "converted private key " << private_key << " to experience_id " << it->second << LL_ENDL;
return it->second;
}
//=========================================================================
void LLExperienceCache::processExperience(const LLUUID& public_key, const LLSD& experience)
{
LL_INFOS("ExperienceCache") << "Processing experience \"" << experience[NAME] << "\" with key " << public_key.asString() << LL_ENDL;
mCache[public_key]=experience;
LLSD & row = mCache[public_key];
if(row.has(EXPIRES))
{
row[EXPIRES] = row[EXPIRES].asReal() + LLFrameTimer::getTotalSeconds();
}
if(row.has(EXPERIENCE_ID))
{
mPendingQueue.erase(row[EXPERIENCE_ID].asUUID());
}
//signal
signal_map_t::iterator sig_it = mSignalMap.find(public_key);
if (sig_it != mSignalMap.end())
{
signal_ptr signal = sig_it->second;
(*signal)(experience);
mSignalMap.erase(public_key);
}
}
const LLExperienceCache::cache_t& LLExperienceCache::getCached()
{
return mCache;
}
void LLExperienceCache::requestExperiencesCoro(const LLCoroResponder& responder, RequestQueue_t requests)
{
//LL_INFOS("requestExperiencesCoro") << "url: " << url << LL_ENDL;
LLSD result = responder.getContent();
auto status = responder.getStatus();
if (!responder.isGoodStatus(status))
{
F64 now = LLFrameTimer::getTotalSeconds();
auto headers = responder.getHeaders();
// build dummy entries for the failed requests
for (auto request : requests)
{
LLSD exp = get(request);
//leave the properties alone if we already have a cache entry for this xp
if (exp.isUndefined())
{
exp[PROPERTIES] = PROPERTY_INVALID;
}
exp[EXPIRES] = now + LLExperienceCacheImpl::getErrorRetryDeltaTime(status, headers);
exp[EXPERIENCE_ID] = request;
exp["key_type"] = EXPERIENCE_ID;
exp["uuid"] = request;
exp["error"] = status;
exp[QUOTA] = DEFAULT_QUOTA;
processExperience(request, exp);
}
return;
}
LLSD experiences = result["experience_keys"];
for (const auto& row : experiences.array())
{
LLUUID public_key = row[EXPERIENCE_ID].asUUID();
LL_DEBUGS("ExperienceCache") << "Received result for " << public_key
<< " display '" << row[LLExperienceCache::NAME].asString() << "'" << LL_ENDL;
processExperience(public_key, row);
}
LLSD error_ids = result["error_ids"];
for (const auto& err : error_ids.array())
{
LLUUID id = err.asUUID();
LLSD exp;
exp[EXPIRES] = DEFAULT_EXPIRATION;
exp[EXPERIENCE_ID] = id;
exp[PROPERTIES] = PROPERTY_INVALID;
exp[MISSING] = true;
exp[QUOTA] = DEFAULT_QUOTA;
processExperience(id, exp);
LL_WARNS("ExperienceCache") << "LLExperienceResponder::result() error result for " << id << LL_ENDL;
}
}
void LLExperienceCache::requestExperiences()
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string urlBase = mCapability("GetExperienceInfo");
if (urlBase.empty())
{
LL_DEBUGS("ExperienceCache") << "No Experience capability." << LL_ENDL;
return;
}
if (*urlBase.rbegin() != '/')
{
urlBase += "/";
}
urlBase += "id/";
F64 now = LLFrameTimer::getTotalSeconds();
const U32 EXP_URL_SEND_THRESHOLD = 3000;
constexpr U32 EXP_PAGE_SIZE = EXP_URL_SEND_THRESHOLD / UUID_STR_LENGTH;
std::ostringstream ostr;
ostr << urlBase << "?page_size=" << EXP_PAGE_SIZE;
RequestQueue_t requests;
while (!mRequestQueue.empty())
{
RequestQueue_t::iterator it = mRequestQueue.begin();
LLUUID key = (*it);
mRequestQueue.erase(it);
requests.insert(key);
ostr << "&" << EXPERIENCE_ID << "=" << key.asString();
mPendingQueue[key] = now;
if (mRequestQueue.empty() || (ostr.tellp() > EXP_URL_SEND_THRESHOLD))
{ // request is placed in the coprocedure pool for the ExpCache cache. Throttling is done by the pool itself.
LLHTTPClient::get(ostr.str(), new LLCoroResponder(
boost::bind(&LLExperienceCache::requestExperiencesCoro, this, _1, requests) ));
ostr.str(std::string());
ostr << urlBase << "?page_size=" << EXP_PAGE_SIZE;
requests.clear();
}
}
}
bool LLExperienceCache::isRequestPending(const LLUUID& public_key)
{
bool isPending = false;
const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
PendingQueue_t::const_iterator it = mPendingQueue.find(public_key);
if(it != mPendingQueue.end())
{
F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
isPending = (it->second > expire_time);
}
return isPending;
}
void LLExperienceCache::setCapabilityQuery(LLExperienceCache::CapabilityQuery_t queryfn)
{
mCapability = queryfn;
}
void LLExperienceCache::idleCoro()
{
const F32 SECS_BETWEEN_REQUESTS = 0.5f;
const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
{
static LLFrameTimer sRequestTimer;
if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) return;
if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
{
eraseExpired();
}
if (!mRequestQueue.empty())
{
requestExperiences();
}
}
// The coroutine system will likely be shut down by the time we get to this point
// (or at least no further cycling will occur on it since the user has decided to quit.)
}
void LLExperienceCache::erase(const LLUUID& key)
{
cache_t::iterator it = mCache.find(key);
if(it != mCache.end())
{
mCache.erase(it);
}
}
void LLExperienceCache::eraseExpired()
{
F64 now = LLFrameTimer::getTotalSeconds();
cache_t::iterator it = mCache.begin();
while (it != mCache.end())
{
cache_t::iterator cur = it;
LLSD& exp = cur->second;
++it;
//LL_INFOS("ExperienceCache") << "Testing experience \"" << exp[NAME] << "\" with exp time " << exp[EXPIRES].asReal() << "(now = " << now << ")" << LL_ENDL;
if(exp.has(EXPIRES) && exp[EXPIRES].asReal() < now)
{
if(!exp.has(EXPERIENCE_ID))
{
LL_WARNS("ExperienceCache") << "Removing experience with no id " << LL_ENDL ;
mCache.erase(cur);
}
else
{
LLUUID id = exp[EXPERIENCE_ID].asUUID();
LLUUID private_key = exp.has(LLExperienceCache::PRIVATE_KEY) ? exp[LLExperienceCache::PRIVATE_KEY].asUUID():LLUUID::null;
if(private_key.notNull() || !exp.has("DoesNotExist"))
{
fetch(id, true);
}
else
{
LL_WARNS("ExperienceCache") << "Removing invalid experience " << id << LL_ENDL ;
mCache.erase(cur);
}
}
}
}
}
bool LLExperienceCache::fetch(const LLUUID& key, bool refresh/* = true*/)
{
if(!key.isNull() && !isRequestPending(key) && (refresh || mCache.find(key)==mCache.end()))
{
LL_DEBUGS("ExperienceCache") << " queue request for " << EXPERIENCE_ID << " " << key << LL_ENDL;
mRequestQueue.insert(key);
return true;
}
return false;
}
void LLExperienceCache::insert(const LLSD& experience_data)
{
if(experience_data.has(EXPERIENCE_ID))
{
processExperience(experience_data[EXPERIENCE_ID].asUUID(), experience_data);
}
else
{
LL_WARNS("ExperienceCache") << ": Ignoring cache insert of experience which is missing " << EXPERIENCE_ID << LL_ENDL;
}
}
const LLSD& LLExperienceCache::get(const LLUUID& key)
{
static const LLSD empty;
if(key.isNull())
return empty;
cache_t::const_iterator it = mCache.find(key);
if (it != mCache.end())
{
return it->second;
}
fetch(key);
return empty;
}
void LLExperienceCache::get(const LLUUID& key, LLExperienceCache::ExperienceGetFn_t slot)
{
if(key.isNull())
return;
cache_t::const_iterator it = mCache.find(key);
if (it != mCache.end())
{
// ...name already exists in cache, fire callback now
callback_signal_t signal;
signal.connect(slot);
signal(it->second);
return;
}
fetch(key);
signal_ptr signal = boost::make_shared<callback_signal_t>();
std::pair<signal_map_t::iterator, bool> result = mSignalMap.insert(signal_map_t::value_type(key, signal));
if (!result.second)
signal = (*result.first).second;
signal->connect(slot);
}
//=========================================================================
void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
if (url.empty())
{
url = mCapability("GetMetadata");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
return;
}
}
LLSD fields;
fields.append("experience");
LLSD data;
data["object-id"] = objectId;
data["item-id"] = itemId;
data["fields"] = fields;
LLHTTPClient::post(url, data, new LLCoroResponder(
boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, fn)));
}
void LLExperienceCache::fetchAssociatedExperienceCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
LLSD result = responder.getContent();
auto status = responder.getStatus();
if (!responder.isGoodStatus(status) || !result.has("experience"))
{
LLSD failure;
if (!status)
{
failure["error"] = status;
failure["message"] = responder.getReason();
}
else
{
failure["error"] = -1;
failure["message"] = "no experience";
}
if (fn != nullptr)
fn(failure);
return;
}
LLUUID expId = result["experience"].asUUID();
get(expId, fn);
}
//-------------------------------------------------------------------------
void LLExperienceCache::findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::ostringstream url;
url << mCapability("FindExperienceByName") << "?page=" << page << "&page_size=" << SEARCH_PAGE_SIZE << "&query=" << LLURI::escape(text);
LLHTTPClient::get(url.str(), new LLCoroResponder(
boost::bind(&LLExperienceCache::findExperienceByNameCoro, this, _1, fn)));
}
void LLExperienceCache::findExperienceByNameCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
LLSD result = responder.getContent();
if (!responder.isGoodStatus(responder.getStatus()))
{
fn(LLSD());
return;
}
const LLSD& experiences = result["experience_keys"];
for (const auto& it : experiences.array())
{
insert(it);
}
fn(result);
}
//-------------------------------------------------------------------------
void LLExperienceCache::getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
// search for experiences owned by the current group
std::string url = mCapability("GroupExperiences");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Group Experiences capability" << LL_ENDL;
return;
}
url += "?" + groupId.asString();
LLHTTPClient::get(url, new LLCoroResponder(
boost::bind(&LLExperienceCache::getGroupExperiencesCoro, this, _1, fn)));
}
void LLExperienceCache::getGroupExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
LLSD result = responder.getContent();
if (!responder.isGoodStatus(responder.getStatus()))
{
fn(LLSD());
return;
}
const LLSD& experienceIds = result["experience_ids"];
fn(experienceIds);
}
//-------------------------------------------------------------------------
void LLExperienceCache::getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn)
{
regionExperiences(regioncaps, LLSD(), false, fn);
}
void LLExperienceCache::setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn)
{
regionExperiences(regioncaps, experiences, true, fn);
}
void LLExperienceCache::regionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, bool update, ExperienceGetFn_t fn)
{
// search for experiences owned by the current group
std::string url = regioncaps("RegionExperiences");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
return;
}
auto httpRequest = new LLCoroResponder(
boost::bind(&LLExperienceCache::regionExperiencesCoro, this, _1, fn));
LLSD result;
if (update)
LLHTTPClient::post(url, experiences, httpRequest);
else
LLHTTPClient::get(url, httpRequest);
}
void LLExperienceCache::regionExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
LLSD result = responder.getContent();
if (!responder.isGoodStatus(responder.getStatus()))
{
// fn(LLSD());
return;
}
fn(result);
}
//-------------------------------------------------------------------------
void LLExperienceCache::getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString();
LLHTTPClient::get(url, new LLCoroResponder(
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
}
void LLExperienceCache::setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("ExperiencePreferences");
if (url.empty())
return;
LLSD permData;
LLSD data;
permData["permission"] = permission;
data[experienceId.asString()] = permData;
LLHTTPClient::put(url, data, new LLCoroResponder(
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
}
void LLExperienceCache::forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString();
LLHTTPClient::del(url, new LLCoroResponder(
boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, fn)));
}
void LLExperienceCache::experiencePermissionCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn)
{
// search for experiences owned by the current group
LLSD result = responder.getContent();
if (responder.isGoodStatus(responder.getStatus()))
{
fn(result);
}
}
//-------------------------------------------------------------------------
void LLExperienceCache::getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("IsExperienceAdmin");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
return;
}
url += "?experience_id=" + experienceId.asString();
LLHTTPClient::get(url, new LLCoroResponder(
boost::bind(fn, boost::bind(&LLCoroResponder::getContent, _1))));
}
//-------------------------------------------------------------------------
void LLExperienceCache::updateExperience(LLSD updateData, ExperienceGetFn_t fn)
{
if (mCapability == nullptr)
{
LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
return;
}
std::string url = mCapability("UpdateExperience");
if (url.empty())
{
LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL;
return;
}
updateData.erase(LLExperienceCache::QUOTA);
updateData.erase(LLExperienceCache::EXPIRES);
updateData.erase(LLExperienceCache::AGENT_ID);
LLHTTPClient::post(url, updateData, new LLCoroResponder(
boost::bind(fn, boost::bind(&LLCoroResponder::getContent, _1))));
}
//=========================================================================
void LLExperienceCacheImpl::mapKeys(const LLSD& legacyKeys)
{
for (const auto& exp : legacyKeys.array())
{
if (exp.has(LLExperienceCacheImpl::EXPERIENCE_ID) && exp.has(LLExperienceCacheImpl::PRIVATE_KEY))
{
LLExperienceCacheImpl::privateToPublicKeyMap[exp[LLExperienceCacheImpl::PRIVATE_KEY].asUUID()] =
exp[LLExperienceCacheImpl::EXPERIENCE_ID].asUUID();
}
}
}
// Return time to retry a request that generated an error, based on
// error type and headers. Return value is seconds-since-epoch.
F64 LLExperienceCacheImpl::getErrorRetryDeltaTime(S32 status, const AIHTTPReceivedHeaders& headers)
{
// Retry-After takes priority
std::string retry_afters;
if (headers.getFirstValue("retry-after", retry_afters))
{
LLSD retry_after(retry_afters);
// We only support the delta-seconds type
S32 delta_seconds = retry_after.asInteger();
if (delta_seconds > 0)
{
// ...valid delta-seconds
return F64(delta_seconds);
}
}
// If no Retry-After, look for Cache-Control max-age
// Allow the header to override the default
std::string cache_control;
if (headers.getFirstValue("cache-control", cache_control))
{
S32 max_age = 0;
if (LLExperienceCacheImpl::maxAgeFromCacheControl(cache_control, &max_age))
{
LL_WARNS("ExperienceCache")
<< "got EXPIRES from headers, max_age " << max_age
<< LL_ENDL;
return (F64)max_age;
}
}
// No information in header, make a guess
if (status == 503)
{
// ...service unavailable, retry soon
const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
return SERVICE_UNAVAILABLE_DELAY;
}
else if (status == 499)
{
// ...we were probably too busy, retry quickly
const F64 BUSY_DELAY = 10.0; // 10 seconds
return BUSY_DELAY;
}
else
{
// ...other unexpected error
const F64 DEFAULT_DELAY = 3600.0; // 1 hour
return DEFAULT_DELAY;
}
}
bool LLExperienceCacheImpl::maxAgeFromCacheControl(const std::string& cache_control, S32 *max_age)
{
// Split the string on "," to get a list of directives
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
tokenizer directives(cache_control, COMMA_SEPARATOR);
tokenizer::iterator token_it = directives.begin();
for ( ; token_it != directives.end(); ++token_it)
{
// Tokens may have leading or trailing whitespace
std::string token = *token_it;
LLStringUtil::trim(token);
if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0)
{
// ...this token starts with max-age, so let's chop it up by "="
tokenizer subtokens(token, EQUALS_SEPARATOR);
tokenizer::iterator subtoken_it = subtokens.begin();
// Must have a token
if (subtoken_it == subtokens.end()) return false;
std::string subtoken = *subtoken_it;
// Must exactly equal "max-age"
LLStringUtil::trim(subtoken);
if (subtoken != MAX_AGE) return false;
// Must have another token
++subtoken_it;
if (subtoken_it == subtokens.end()) return false;
subtoken = *subtoken_it;
// Must be a valid integer
// *NOTE: atoi() returns 0 for invalid values, so we have to
// check the string first.
// *TODO: Do servers ever send "0000" for zero? We don't handle it
LLStringUtil::trim(subtoken);
if (subtoken == "0")
{
*max_age = 0;
return true;
}
S32 val = atoi( subtoken.c_str() );
if (val > 0 && val < S32_MAX)
{
*max_age = val;
return true;
}
return false;
}
}
return false;
}

View File

@@ -0,0 +1,181 @@
/**
* @file llexperiencecache.h
* @brief Caches information relating to experience keys
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012, 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 LL_LLEXPERIENCECACHE_H
#define LL_LLEXPERIENCECACHE_H
#include "linden_common.h"
#include "llsingleton.h"
#include "llframetimer.h"
#include "llsd.h"
#include <boost/signals2.hpp>
struct LLCoroResponder;
class LLSD;
class LLUUID;
class LLExperienceCache final : public LLSingleton < LLExperienceCache >
{
friend class LLSingleton<LLExperienceCache>;
LLExperienceCache();
public:
typedef std::function<std::string(const std::string &)> CapabilityQuery_t;
typedef std::function<void(const LLSD &)> ExperienceGetFn_t;
void idleCoro();
void setCapabilityQuery(CapabilityQuery_t queryfn);
void cleanup();
//-------------------------------------------
// Cache methods
void erase(const LLUUID& key);
bool fetch(const LLUUID& key, bool refresh = false);
void insert(const LLSD& experience_data);
const LLSD& get(const LLUUID& key);
void get(const LLUUID& key, ExperienceGetFn_t slot); // If name information is in cache, callback will be called immediately.
bool isRequestPending(const LLUUID& public_key);
//-------------------------------------------
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, ExperienceGetFn_t fn) { fetchAssociatedExperience(objectId, itemId, LLStringUtil::null, fn); }
void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn);
void findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn);
void getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn);
// the Get/Set Region Experiences take a CapabilityQuery to get the capability since
// the region being queried may not be the region that the agent is standing on.
void getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn);
void setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn);
void getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn);
void setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn);
void forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn);
void getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn);
void updateExperience(LLSD updateData, ExperienceGetFn_t fn);
//-------------------------------------------
static const std::string NAME; // "name"
static const std::string EXPERIENCE_ID; // "public_id"
static const std::string AGENT_ID; // "agent_id"
static const std::string GROUP_ID; // "group_id"
static const std::string PROPERTIES; // "properties"
static const std::string EXPIRES; // "expiration"
static const std::string DESCRIPTION; // "description"
static const std::string QUOTA; // "quota"
static const std::string MATURITY; // "maturity"
static const std::string METADATA; // "extended_metadata"
static const std::string SLURL; // "slurl"
static const std::string MISSING; // "DoesNotExist"
// should be in sync with experience-api/experiences/models.py
static const int PROPERTY_INVALID; // 1 << 0
static const int PROPERTY_PRIVILEGED; // 1 << 3
static const int PROPERTY_GRID; // 1 << 4
static const int PROPERTY_PRIVATE; // 1 << 5
static const int PROPERTY_DISABLED; // 1 << 6
static const int PROPERTY_SUSPENDED; // 1 << 7
private:
virtual ~LLExperienceCache();
void initSingleton() override;
// Callback types for get()
typedef boost::signals2::signal < void(const LLSD &) > callback_signal_t;
typedef boost::shared_ptr<callback_signal_t> signal_ptr;
// May have multiple callbacks for a single ID, which are
// represented as multiple slots bound to the signal.
// Avoid copying signals via pointers.
typedef std::map<LLUUID, signal_ptr> signal_map_t;
typedef std::map<LLUUID, LLSD> cache_t;
typedef uuid_set_t RequestQueue_t;
typedef std::map<LLUUID, F64> PendingQueue_t;
//--------------------------------------------
static const std::string PRIVATE_KEY; // "private_id"
// default values
static const F64 DEFAULT_EXPIRATION; // 600.0
static const S32 DEFAULT_QUOTA; // 128 this is megabytes
static const int SEARCH_PAGE_SIZE;
//--------------------------------------------
void processExperience(const LLUUID& public_key, const LLSD& experience);
//--------------------------------------------
cache_t mCache;
signal_map_t mSignalMap;
RequestQueue_t mRequestQueue;
PendingQueue_t mPendingQueue;
LLFrameTimer mEraseExpiredTimer; // Periodically clean out expired entries from the cache
CapabilityQuery_t mCapability;
std::string mCacheFileName;
bool mShutdown;
void eraseExpired();
void requestExperiencesCoro(const LLCoroResponder& responder, RequestQueue_t);
void requestExperiences();
void fetchAssociatedExperienceCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
void findExperienceByNameCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
void getGroupExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t);
void regionExperiences(CapabilityQuery_t regioncaps, const LLSD& experiences, bool update, ExperienceGetFn_t fn);
void regionExperiencesCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn);
void experiencePermissionCoro(const LLCoroResponder& responder, ExperienceGetFn_t fn);
void bootstrap(const LLSD& legacyKeys, int initialExpiration);
void exportFile(std::ostream& ostr) const;
void importFile(std::istream& istr);
//
const cache_t& getCached();
// maps an experience private key to the experience id
LLUUID getExperienceId(const LLUUID& private_key, bool null_if_not_found=false);
//=====================================================================
inline friend std::ostream &operator << (std::ostream &os, const LLExperienceCache &cache)
{
cache.exportFile(os);
return os;
}
inline friend std::istream &operator >> (std::istream &is, LLExperienceCache &cache)
{
cache.importFile(is);
return is;
}
};
#endif // LL_LLEXPERIENCECACHE_H

View File

@@ -58,103 +58,6 @@ const std::string SYSTEM_FROM("Second Life");
const std::string INTERACTIVE_SYSTEM_FROM("F387446C-37C4-45f2-A438-D99CBDBB563B");
const S32 IM_TTL = 1;
/**
* LLIMInfo
*/
LLIMInfo::LLIMInfo() :
mFromGroup(FALSE),
mParentEstateID(0),
mOffline(0),
mViewerThinksToIsOnline(false),
mIMType(IM_NOTHING_SPECIAL),
mTimeStamp(0),
mSource(IM_FROM_SIM),
mTTL(IM_TTL)
{
}
LLIMInfo::LLIMInfo(
const LLUUID& from_id,
BOOL from_group,
const LLUUID& to_id,
EInstantMessage im_type,
const std::string& name,
const std::string& message,
const LLUUID& id,
U32 parent_estate_id,
const LLUUID& region_id,
const LLVector3& position,
LLSD data,
U8 offline,
U32 timestamp,
EIMSource source,
S32 ttl) :
mFromID(from_id),
mFromGroup(from_group),
mToID(to_id),
mParentEstateID(0),
mRegionID(region_id),
mPosition(position),
mOffline(offline),
mViewerThinksToIsOnline(false),
mIMType(im_type),
mID(id),
mTimeStamp(timestamp),
mName(name),
mMessage(message),
mData(data),
mSource(source),
mTTL(ttl)
{
}
LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
mViewerThinksToIsOnline(false),
mSource(source),
mTTL(ttl)
{
unpackMessageBlock(msg);
}
LLIMInfo::~LLIMInfo()
{
}
void LLIMInfo::packInstantMessage(LLMessageSystem* msg) const
{
LL_DEBUGS() << "LLIMInfo::packInstantMessage()" << LL_ENDL;
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
packMessageBlock(msg);
}
void LLIMInfo::packMessageBlock(LLMessageSystem* msg) const
{
// Construct binary bucket
std::vector<U8> bucket;
if (mData.has("binary_bucket"))
{
bucket = mData["binary_bucket"].asBinary();
}
pack_instant_message_block(
msg,
mFromID,
mFromGroup,
LLUUID::null,
mToID,
mName,
mMessage,
mOffline,
mIMType,
mID,
mParentEstateID,
mRegionID,
mPosition,
mTimeStamp,
&bucket[0],
bucket.size());
}
void pack_instant_message(
LLMessageSystem* msg,
const LLUUID& from_id,
@@ -264,124 +167,3 @@ void pack_instant_message_block(
}
msg->addBinaryDataFast(_PREHASH_BinaryBucket, bb, binary_bucket_size);
}
void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)
{
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, mFromID);
msg->getBOOLFast(_PREHASH_MessageBlock, _PREHASH_FromGroup, mFromGroup);
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ToAgentID, mToID);
msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, mParentEstateID);
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, mRegionID);
msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, mPosition);
msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Offline, mOffline);
U8 dialog;
msg->getU8Fast(_PREHASH_MessageBlock, _PREHASH_Dialog, dialog);
mIMType = (EInstantMessage) dialog;
msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, mID);
msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_Timestamp, mTimeStamp);
msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, mName);
msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, mMessage);
S32 binary_bucket_size = llmin(
MTUBYTES,
msg->getSizeFast(
_PREHASH_MessageBlock,
_PREHASH_BinaryBucket));
if(binary_bucket_size > 0)
{
std::vector<U8> bucket;
bucket.resize(binary_bucket_size);
msg->getBinaryDataFast(
_PREHASH_MessageBlock,
_PREHASH_BinaryBucket,
&bucket[0],
0,
0,
binary_bucket_size);
mData["binary_bucket"] = bucket;
}
else
{
mData.clear();
}
}
LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
{
LLSD param_version;
param_version["version"] = 1;
LLSD param_message;
param_message["from_id"] = im_info->mFromID;
param_message["from_group"] = im_info->mFromGroup;
param_message["to_id"] = im_info->mToID;
param_message["from_name"] = im_info->mName;
param_message["message"] = im_info->mMessage;
param_message["type"] = (S32)im_info->mIMType;
param_message["id"] = im_info->mID;
param_message["timestamp"] = (S32)im_info->mTimeStamp;
param_message["offline"] = (S32)im_info->mOffline;
param_message["parent_estate_id"] = (S32)im_info->mParentEstateID;
param_message["region_id"] = im_info->mRegionID;
param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
param_message["data"] = im_info->mData;
param_message["source"]= im_info->mSource;
param_message["ttl"] = im_info->mTTL;
LLSD param_agent;
param_agent["agent_id"] = im_info->mFromID;
LLSD params;
params["version_params"] = param_version;
params["message_params"] = param_message;
params["agent_params"] = param_agent;
return params;
}
LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
{
LLSD param_message = im_info_sd["message_params"];
LLSD param_agent = im_info_sd["agent_params"];
LLPointer<LLIMInfo> im_info = new LLIMInfo(
param_message["from_id"].asUUID(),
param_message["from_group"].asBoolean(),
param_message["to_id"].asUUID(),
(EInstantMessage) param_message["type"].asInteger(),
param_message["from_name"].asString(),
param_message["message"].asString(),
param_message["id"].asUUID(),
(U32) param_message["parent_estate_id"].asInteger(),
param_message["region_id"].asUUID(),
ll_vector3_from_sd(param_message["position"]),
param_message["data"],
(U8) param_message["offline"].asInteger(),
(U32) param_message["timestamp"].asInteger(),
(EIMSource)param_message["source"].asInteger(),
param_message["ttl"].asInteger());
return im_info;
}
LLPointer<LLIMInfo> LLIMInfo::clone()
{
return new LLIMInfo(
mFromID,
mFromGroup,
mToID,
mIMType,
mName,
mMessage,
mID,
mParentEstateID,
mRegionID,
mPosition,
mData,
mOffline,
mTimeStamp,
mSource,
mTTL);
}

View File

@@ -225,62 +225,6 @@ extern const std::string INTERACTIVE_SYSTEM_FROM;
// Number of retry attempts on sending the im.
extern const S32 IM_TTL;
class LLIMInfo : public LLRefCount
{
protected:
LLIMInfo();
~LLIMInfo();
public:
LLIMInfo(LLMessageSystem* msg,
EIMSource source = IM_FROM_SIM,
S32 ttl = IM_TTL);
LLIMInfo(
const LLUUID& from_id,
BOOL from_group,
const LLUUID& to_id,
EInstantMessage im_type,
const std::string& name,
const std::string& message,
const LLUUID& id,
U32 parent_estate_id,
const LLUUID& region_id,
const LLVector3& position,
LLSD data,
U8 offline,
U32 timestamp,
EIMSource source,
S32 ttl = IM_TTL);
void packInstantMessage(LLMessageSystem* msg) const;
void packMessageBlock(LLMessageSystem* msg) const;
void unpackMessageBlock(LLMessageSystem* msg);
LLPointer<LLIMInfo> clone();
public:
LLUUID mFromID;
BOOL mFromGroup;
LLUUID mToID;
U32 mParentEstateID;
LLUUID mRegionID;
LLVector3 mPosition;
U8 mOffline;
bool mViewerThinksToIsOnline;
EInstantMessage mIMType;
LLUUID mID;
U32 mTimeStamp;
std::string mName;
std::string mMessage;
LLSD mData;
EIMSource mSource;
S32 mTTL;
};
LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd);
LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info);
void pack_instant_message(
LLMessageSystem* msgsystem,
const LLUUID& from_id,

View File

@@ -168,19 +168,20 @@ const U32 ESTATE_ACCESS_ALL = ESTATE_ACCESS_ALLOWED_AGENTS
| ESTATE_ACCESS_BANNED_AGENTS
| ESTATE_ACCESS_MANAGERS;
// for EstateOwnerRequest, estateaccessdelta message
const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1 << 0;
const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1 << 1;
// for EstateOwnerRequest, estateaccessdelta, estateexperiencedelta messages
const U32 ESTATE_ACCESS_APPLY_TO_ALL_ESTATES = 1U << 0;
const U32 ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES = 1U << 1;
const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1 << 2;
const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1 << 3;
const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1 << 4;
const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1 << 5;
const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1 << 6;
const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1 << 7;
const U32 ESTATE_ACCESS_MANAGER_ADD = 1 << 8;
const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1 << 9;
const U32 ESTATE_ACCESS_NO_REPLY = 1 << 10;
const U32 ESTATE_ACCESS_ALLOWED_AGENT_ADD = 1U << 2;
const U32 ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1U << 3;
const U32 ESTATE_ACCESS_ALLOWED_GROUP_ADD = 1U << 4;
const U32 ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 1U << 5;
const U32 ESTATE_ACCESS_BANNED_AGENT_ADD = 1U << 6;
const U32 ESTATE_ACCESS_BANNED_AGENT_REMOVE = 1U << 7;
const U32 ESTATE_ACCESS_MANAGER_ADD = 1U << 8;
const U32 ESTATE_ACCESS_MANAGER_REMOVE = 1U << 9;
const U32 ESTATE_ACCESS_NO_REPLY = 1U << 10;
const U32 ESTATE_ACCESS_FAILED_BAN_ESTATE_MANAGER = 1U << 11;
const S32 ESTATE_MAX_MANAGERS = 15;
const S32 ESTATE_MAX_ACCESS_IDS = 500; // max for access, banned
@@ -191,6 +192,26 @@ const U32 SWD_OTHERS_LAND_ONLY = (1 << 0);
const U32 SWD_ALWAYS_RETURN_OBJECTS = (1 << 1);
const U32 SWD_SCRIPTED_ONLY = (1 << 2);
// Controls experience key validity in the estate
const U32 EXPERIENCE_KEY_TYPE_NONE = 0;
const U32 EXPERIENCE_KEY_TYPE_BLOCKED = 1;
const U32 EXPERIENCE_KEY_TYPE_ALLOWED = 2;
const U32 EXPERIENCE_KEY_TYPE_TRUSTED = 3;
const U32 EXPERIENCE_KEY_TYPE_FIRST = EXPERIENCE_KEY_TYPE_BLOCKED;
const U32 EXPERIENCE_KEY_TYPE_LAST = EXPERIENCE_KEY_TYPE_TRUSTED;
//
const U32 ESTATE_EXPERIENCE_TRUSTED_ADD = 1U << 2;
const U32 ESTATE_EXPERIENCE_TRUSTED_REMOVE = 1U << 3;
const U32 ESTATE_EXPERIENCE_ALLOWED_ADD = 1U << 4;
const U32 ESTATE_EXPERIENCE_ALLOWED_REMOVE = 1U << 5;
const U32 ESTATE_EXPERIENCE_BLOCKED_ADD = 1U << 6;
const U32 ESTATE_EXPERIENCE_BLOCKED_REMOVE = 1U << 7;
const S32 ESTATE_MAX_EXPERIENCE_IDS = 8;
#endif

View File

@@ -1393,6 +1393,8 @@ char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance
char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion");
char const* const _PREHASH_AppearanceHover = LLMessageStringTable::getInstance()->getString("AppearanceHover");
char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->getString("HoverHeight");
char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience");
char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID");
// <FS:CR> Aurora Sim
char const* const _PREHASH_RegionSizeX = LLMessageStringTable::getInstance()->getString("RegionSizeX");

View File

@@ -1393,6 +1393,8 @@ extern char const* const _PREHASH_AppearanceVersion;
extern char const* const _PREHASH_CofVersion;
extern char const* const _PREHASH_AppearanceHover;
extern char const* const _PREHASH_HoverHeight;
extern char const* const _PREHASH_Experience;
extern char const* const _PREHASH_ExperienceID;
// <FS:CR> Aurora Sim
extern char const* const _PREHASH_RegionSizeX;

View File

@@ -19,7 +19,7 @@ include_directories(
set(llplugin_SOURCE_FILES
llpluginclassbasic.cpp
llpluginclassmedia.cpp
llplugincookiestore.cpp
#llplugincookiestore.cpp
llplugininstance.cpp
llpluginmessage.cpp
llpluginmessagepipe.cpp
@@ -34,7 +34,7 @@ set(llplugin_HEADER_FILES
llpluginclassbasic.h
llpluginclassmedia.h
llpluginclassmediaowner.h
llplugincookiestore.h
#llplugincookiestore.h
llplugininstance.h
llpluginmessage.h
llpluginmessageclasses.h

View File

@@ -623,12 +623,14 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
return result;
}
void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers)
void LLPluginClassMedia::scrollEvent(int x, int y, int clicks_x, int clicks_y, MASK modifiers)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "scroll_event");
message.setValueS32("x", x);
message.setValueS32("y", y);
message.setValueS32("clicks_x", clicks_x);
message.setValueS32("clicks_y", clicks_y);
message.setValue("modifiers", translateModifiers(modifiers));
sendMessage(message);
@@ -711,9 +713,9 @@ void LLPluginClassMedia::sendPickFileResponse(const std::vector<std::string> fil
}
LLSD file_list = LLSD::emptyArray();
for (std::vector<std::string>::const_iterator in_iter = files.begin(); in_iter != files.end(); ++in_iter)
for (const auto& file : files)
{
file_list.append(LLSD::String(*in_iter));
file_list.append(LLSD::String(file));
}
message.setValueLLSD("file_list", file_list);

View File

@@ -75,7 +75,7 @@ public:
void setAutoScale(bool auto_scale);
void setZoomFactor(F64 zoom_factor) { mZoomFactor = zoom_factor; }
void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
void setBackgroundColor(const LLColor4& color) { mBackgroundColor = color; };
void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
@@ -107,7 +107,7 @@ public:
bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);
void scrollEvent(int x, int y, MASK modifiers);
void scrollEvent(int x, int y, int clicks_x, int clicks_y, MASK modifiers);
// enable/disable media plugin debugging messages and info spam
void enableMediaPluginDebugging( bool enable );

View File

@@ -37,6 +37,7 @@ set(llui_SOURCE_FILES
lldraghandle.cpp
lleditmenuhandler.cpp
llfiltereditor.cpp
llflatlistview.cpp
llfloater.cpp
llflyoutbutton.cpp
llfocusmgr.cpp
@@ -116,6 +117,7 @@ set(llui_HEADER_FILES
lldraghandle.h
lleditmenuhandler.h
llfiltereditor.h
llflatlistview.h
llfloater.h
llflyoutbutton.h
llfocusmgr.h

View File

@@ -27,6 +27,7 @@ const std::array<const std::string, LFIDBearer::COUNT> LFIDBearer::sMenuStrings
"menu_avs_list.xml" // 0
, "menu_groups_list.xml" // 1
, "menu_objects_list.xml" // 2
, "menu_experiences.xml" // 3
};
std::array<LLMenuGL*, LFIDBearer::COUNT> LFIDBearer::sMenus {};

View File

@@ -34,6 +34,7 @@ struct LFIDBearer
AVATAR = 0,
GROUP,
OBJECT,
EXPERIENCE,
COUNT
};

View File

@@ -446,8 +446,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
if (!mAllowTextEntry)
{
mButton->setLabelUnselected(name);
mButton->setLabelSelected(name);
mButton->setLabel(name);
}
}
@@ -465,9 +464,7 @@ void LLComboBox::updateLabel()
// the combo button label.
if (!mAllowTextEntry)
{
std::string label = getSelectedItemLabel();
mButton->setLabelUnselected(label);
mButton->setLabelSelected(label);
mButton->setLabel(getSelectedItemLabel());
}
}
@@ -513,13 +510,16 @@ void LLComboBox::onFocusLost()
void LLComboBox::setButtonVisible(BOOL visible)
{
static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
mButton->setVisible(visible);
if (mTextEntry)
{
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
if (visible)
{
text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * LLUI::sConfigGroup->getS32("DropShadowButton");
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
}
//mTextEntry->setRect(text_entry_rect);
mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
@@ -558,18 +558,21 @@ S32 LLComboBox::getCurrentIndex() const
void LLComboBox::updateLayout()
{
static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
LLRect rect = getLocalRect();
if (mAllowTextEntry)
{
S32 shadow_size = LLUI::sConfigGroup->getS32("DropShadowButton");
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,mArrowImage->getWidth()) - 2 * shadow_size,
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
S32 shadow_size = drop_shadow_button;
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size,
rect.mTop, rect.mRight, rect.mBottom));
mButton->setTabStop(FALSE);
mButton->setHAlign(LLFontGL::HCENTER);
if (!mTextEntry)
{
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
text_entry_rect.mRight -= llmax(8,mArrowImage->getWidth()) + 2 * shadow_size;
text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
// clear label on button
std::string cur_label = mButton->getLabelSelected();
mTextEntry = new LLLineEditor(std::string("combo_text_entry"),
@@ -718,6 +721,7 @@ void LLComboBox::showList()
mList->setVisible(TRUE);
setUseBoundingRect(TRUE);
// updateBoundingRect();
}
void LLComboBox::hideList()
@@ -744,6 +748,7 @@ void LLComboBox::hideList()
{
gFocusMgr.setTopCtrl(NULL);
}
// updateBoundingRect();
}
}
@@ -1029,9 +1034,7 @@ void LLComboBox::onTextEntry(LLLineEditor* line_editor)
void LLComboBox::updateSelection()
{
if(mSuppressAutoComplete) {
return;
}
if(mSuppressAutoComplete) return;
LLWString left_wstring = mTextEntry->getWText().substr(0, mTextEntry->getCursor());
// user-entered portion of string, based on assumption that any selected
@@ -1242,3 +1245,25 @@ BOOL LLComboBox::selectItemRange( S32 first, S32 last )
return mList->selectItemRange(first, last);
}
/* Singu Note: This isn't very necessary for now, let's not bother.
static LLRegisterWidget<LLIconsComboBox> register_icons_combo_box("icons_combo_box");
LLIconsComboBox::Params::Params()
: icon_column("icon_column", ICON_COLUMN),
label_column("label_column", LABEL_COLUMN)
{}
LLIconsComboBox::LLIconsComboBox(const LLIconsComboBox::Params& p)
: LLComboBox(p),
mIconColumnIndex(p.icon_column),
mLabelColumnIndex(p.label_column)
{}
const std::string LLIconsComboBox::getSelectedItemLabel(S32 column) const
{
mButton->setImageOverlay(LLComboBox::getSelectedItemLabel(mIconColumnIndex), mButton->getImageOverlayHAlign());
return LLComboBox::getSelectedItemLabel(mLabelColumnIndex);
}
*/

File diff suppressed because it is too large Load Diff

540
indra/llui/llflatlistview.h Normal file
View File

@@ -0,0 +1,540 @@
/**
* @file llflatlistview.h
* @brief LLFlatListView base class and extension to support messages for several cases of an empty list.
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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 LL_LLFLATLISTVIEW_H
#define LL_LLFLATLISTVIEW_H
#include "llpanel.h"
#include "llscrollcontainer.h"
#include "lltextbox.h"
/**
* LLFlatListView represents a flat list ui control that operates on items in a form of LLPanel's.
* LLSD can be associated with each added item, it can keep data from an item in digested form.
* Associated LLSD's can be of any type (singular, a map etc.).
* Items (LLPanel's subclasses) can be of different height.
* The list is LLPanel created in itself and grows in height while new items are added.
*
* The control can manage selection of its items when the flag "allow_select" is set. Also ability to select
* multiple items (by using CTRL) is enabled through setting the flag "multi_select" - if selection is not allowed that flag
* is ignored. The option "keep_one_selected" forces at least one item to be selected at any time (only for mouse events on items)
* since any item of the list was selected.
*
* Examples of using this control are presented in Picks panel (My Profile and Profile View), where this control is used to
* manage the list of pick items.
*
* ASSUMPTIONS AND STUFF
* - NULL pointers and undefined LLSD's are not accepted by any method of this class unless specified otherwise
* - Order of returned selected items are not guaranteed
* - The control assumes that all items being added are unique.
*/
class LLFlatListView : public LLScrollContainer, public LLEditMenuHandler
{
LOG_CLASS(LLFlatListView);
public:
/**
* Abstract comparator for comparing flat list items in a form of LLPanel
*/
class ItemComparator
{
public:
ItemComparator() {};
virtual ~ItemComparator() {};
/** Returns true if item1 < item2, false otherwise */
virtual bool compare(const LLPanel* item1, const LLPanel* item2) const = 0;
};
/**
* Represents reverse comparator which acts as a decorator for a comparator that need to be reversed
*/
class ItemReverseComparator : public ItemComparator
{
public:
ItemReverseComparator(const ItemComparator& comparator) : mComparator(comparator) {};
virtual ~ItemReverseComparator() {};
bool compare(const LLPanel* item1, const LLPanel* item2) const override
{
return mComparator.compare(item2, item1);
}
private:
const ItemComparator& mComparator;
};
struct Params : public LLInitParam::Block<Params, LLScrollContainer::Params>
{
/** turning on/off selection support */
Optional<bool> allow_select;
/** turning on/off multiple selection (works while clicking and holding CTRL)*/
Optional<bool> multi_select;
/** don't allow to deselect all selected items (for mouse events on items only) */
Optional<bool> keep_one_selected;
/** try to keep selection visible after reshape */
Optional<bool> keep_selection_visible_on_reshape;
/** padding between items */
Optional<U32> item_pad;
/** textbox with info message when list is empty*/
Optional<LLTextBox::Params> no_items_text;
Params();
};
// disable traversal when finding widget to hand focus off to
/*virtual*/ BOOL canFocusChildren() const override { return FALSE; }
/**
* Connects callback to signal called when Return key is pressed.
*/
boost::signals2::connection setReturnCallback( const commit_signal_t::slot_type& cb ) { return mOnReturnSignal.connect(cb); }
/** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
/** Returns full rect of child panel */
const LLRect& getItemsRect() const;
LLRect getRequiredRect() override { return getItemsRect(); }
/** Returns distance between items */
const S32 getItemsPad() const { return mItemPad; }
/**
* Adds and item and LLSD value associated with it to the list at specified position
* @return true if the item was added, false otherwise
*/
virtual bool addItem(LLPanel * item, const LLSD& value = LLUUID::null, EAddPosition pos = ADD_BOTTOM, bool rearrange = true);
/**
* Insert item_to_add along with associated value to the list right after the after_item.
* @return true if the item was successfully added, false otherwise
*/
virtual bool insertItemAfter(LLPanel* after_item, LLPanel* item_to_add, const LLSD& value = LLUUID::null);
/**
* Remove specified item
* @return true if the item was removed, false otherwise
*/
virtual bool removeItem(LLPanel* item, bool rearrange = true);
/**
* Remove an item specified by value
* @return true if the item was removed, false otherwise
*/
virtual bool removeItemByValue(const LLSD& value, bool rearrange = true);
/**
* Remove an item specified by uuid
* @return true if the item was removed, false otherwise
*/
virtual bool removeItemByUUID(const LLUUID& uuid, bool rearrange = true);
/**
* Get an item by value
* @return the item as LLPanel if associated with value, NULL otherwise
*/
virtual LLPanel* getItemByValue(const LLSD& value) const;
/**
* Check for item by value in list
* @return bool whether item exists by value or not
*/
virtual bool valueExists(const LLSD& value) const;
template<class T>
T* getTypedItemByValue(const LLSD& value) const
{
return dynamic_cast<T*>(getItemByValue(value));
}
/**
* Select or deselect specified item based on select
* @return true if succeed, false otherwise
*/
virtual bool selectItem(LLPanel* item, bool select = true);
/**
* Select or deselect an item by associated value based on select
* @return true if succeed, false otherwise
*/
virtual bool selectItemByValue(const LLSD& value, bool select = true);
/**
* Select or deselect an item by associated uuid based on select
* @return true if succeed, false otherwise
*/
virtual bool selectItemByUUID(const LLUUID& uuid, bool select = true);
/**
* Get all panels stored in the list.
*/
virtual void getItems(std::vector<LLPanel*>& items) const;
/**
* Get all items values.
*/
virtual void getValues(std::vector<LLSD>& values) const;
/**
* Get LLSD associated with the first selected item
*/
virtual LLSD getSelectedValue() const;
/**
* Get LLSD's associated with selected items.
* @param selected_values std::vector being populated with LLSD associated with selected items
*/
virtual void getSelectedValues(std::vector<LLSD>& selected_values) const;
/**
* Get LLUUID associated with selected item
* @return LLUUID if such was associated with selected item
*/
virtual LLUUID getSelectedUUID() const;
/**
* Get LLUUIDs associated with selected items
* @param selected_uuids An std::vector being populated with LLUUIDs associated with selected items
*/
virtual void getSelectedUUIDs(uuid_vec_t& selected_uuids) const;
/** Get the top selected item */
virtual LLPanel* getSelectedItem() const;
/**
* Get selected items
* @param selected_items An std::vector being populated with pointers to selected items
*/
virtual void getSelectedItems(std::vector<LLPanel*>& selected_items) const;
/**
* Resets selection of items.
*
* It calls onCommit callback if setCommitOnSelectionChange(bool b) was called with "true"
* argument for current Flat List.
* @param no_commit_on_deselection - if true onCommit callback will not be called
*/
virtual void resetSelection(bool no_commit_on_deselection = false);
/**
* Sets comment text which will be shown in the list is it is empty.
*
* Textbox to hold passed text is created while this method is called at the first time.
*
* @param comment_text - string to be shown as a comment.
*/
void setNoItemsCommentText( const std::string& comment_text);
/** Turn on/off multiple selection support */
void setAllowMultipleSelection(bool allow) { mMultipleSelection = allow; }
/** Turn on/off selection support */
void setAllowSelection(bool can_select) { mAllowSelection = can_select; }
/** Sets flag whether onCommit should be fired if selection was changed */
// FIXME: this should really be a separate signal, since "Commit" implies explicit user action, and selection changes can happen more indirectly.
void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; }
/** Get number of selected items in the list */
U32 numSelected() const {return mSelectedItemPairs.size(); }
/** Get number of (visible) items in the list */
U32 size(const bool only_visible_items = true) const;
/** Removes all items from the list */
void clear() override;
/**
* Removes all items that can be detached from the list but doesn't destroy
* them, caller responsible to manage items after they are detached.
* Detachable item should accept "detach" action via notify() method,
* where it disconnect all callbacks, does other valuable routines and
* return 1.
*/
void detachItems(std::vector<LLPanel*>& detached_items);
/**
* Set comparator to use for future sorts.
*
* This class does NOT manage lifetime of the comparator
* but assumes that the comparator is always alive.
*/
void setComparator(const ItemComparator* comp) { mItemComparator = comp; }
void sort();
bool updateValue(const LLSD& old_value, const LLSD& new_value);
void scrollToShowFirstSelectedItem();
void selectFirstItem ();
void selectLastItem ();
S32 notify(const LLSD& info) override;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory); // <singu> Old-style
virtual ~LLFlatListView();
protected:
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
typedef std::pair<LLPanel*, LLSD> item_pair_t;
typedef std::list<item_pair_t*> pairs_list_t;
typedef pairs_list_t::iterator pairs_iterator_t;
typedef pairs_list_t::const_iterator pairs_const_iterator_t;
/** An adapter for a ItemComparator */
struct ComparatorAdaptor
{
ComparatorAdaptor(const ItemComparator& comparator) : mComparator(comparator) {};
bool operator()(const item_pair_t* item_pair1, const item_pair_t* item_pair2) const
{
return mComparator.compare(item_pair1->first, item_pair2->first);
}
const ItemComparator& mComparator;
};
friend class LLUICtrlFactory;
LLFlatListView(const std::string& name, const LLRect& rect, bool opaque, const LLColor4& color, const S32& item_pad, bool allow_select, bool multi_select, bool keep_one_selected, bool keep_selection_visible_on_reshape, const std::string& no_items_text);
/** Manage selection on mouse events */
void onItemMouseClick(item_pair_t* item_pair, MASK mask);
void onItemRightMouseClick(item_pair_t* item_pair, MASK mask);
/**
* Updates position of items.
* It does not take into account invisible items.
*/
virtual void rearrangeItems();
virtual item_pair_t* getItemPair(LLPanel* item) const;
virtual item_pair_t* getItemPair(const LLSD& value) const;
virtual bool selectItemPair(item_pair_t* item_pair, bool select);
virtual bool selectNextItemPair(bool is_up_direction, bool reset_selection);
BOOL canSelectAll() const override;
void selectAll() override;
virtual bool isSelected(item_pair_t* item_pair) const;
virtual bool removeItemPair(item_pair_t* item_pair, bool rearrange);
bool addItemPairs(pairs_list_t panel_list, bool rearrange = true);
/**
* Notify parent about changed size of internal controls with "size_changes" action
*
* Size includes Items Rect width and either Items Rect height or comment text height.
* Comment text height is included if comment text is set and visible.
* List border size is also included into notified size.
*/
void notifyParentItemsRectChanged();
BOOL handleKeyHere(KEY key, MASK mask) override;
BOOL postBuild() override;
void onFocusReceived() override;
void onFocusLost() override;
void draw() override;
LLRect getLastSelectedItemRect();
void ensureSelectedVisible();
private:
void setItemsNoScrollWidth(S32 new_width) {mItemsNoScrollWidth = new_width - 2 * mBorderThickness;}
void setNoItemsCommentVisible(bool visible) const;
protected:
/** Comparator to use when sorting the list. */
const ItemComparator* mItemComparator;
private:
LLPanel* mItemsPanel;
S32 mItemsNoScrollWidth;
S32 mBorderThickness;
/** Items padding */
S32 mItemPad;
/** Selection support flag */
bool mAllowSelection;
/** Multiselection support flag, ignored if selection is not supported */
bool mMultipleSelection;
/**
* Flag specified whether onCommit be called if selection is changed in the list.
*
* Can be ignored in the resetSelection() method.
* @see resetSelection()
*/
bool mCommitOnSelectionChange;
bool mKeepOneItemSelected;
bool mIsConsecutiveSelection;
bool mKeepSelectionVisibleOnReshape;
/** All pairs of the list */
pairs_list_t mItemPairs;
/** Selected pairs for faster access */
pairs_list_t mSelectedItemPairs;
/**
* Rectangle contained previous size of items parent notified last time.
* Is used to reduce amount of parentNotify() calls if size was not changed.
*/
LLRect mPrevNotifyParentRect;
LLTextBox* mNoItemsCommentTextbox;
LLViewBorder* mSelectedItemsBorder;
commit_signal_t mOnReturnSignal;
};
/**
* Extends LLFlatListView functionality to show different messages when there are no items in the
* list depend on whether they are filtered or not.
*
* Class provides one message per case of empty list.
* It also provides protected updateNoItemsMessage() method to be called each time when derived list
* is changed to update base mNoItemsCommentTextbox value.
*
* It is implemented to avoid duplication of this functionality in concrete implementations of the
* lists. It is intended to be used as a base class for lists which should support two different
* messages for empty state. Can be improved to support more than two messages via state-to-message map.
*/
class LLFlatListViewEx : public LLFlatListView
{
public:
LOG_CLASS(LLFlatListViewEx);
struct Params : public LLInitParam::Block<Params, LLFlatListView::Params>
{
/**
* Contains a message for empty list when it does not contain any items at all.
*/
Optional<std::string> no_items_msg;
/**
* Contains a message for empty list when its items are removed by filtering.
*/
Optional<std::string> no_filtered_items_msg;
Params();
};
// *WORKAROUND: two methods to overload appropriate Params due to localization issue:
// no_items_msg & no_filtered_items_msg attributes are not defined as translatable in VLT. See EXT-5931
void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; }
void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; }
bool getForceShowingUnmatchedItems();
void setForceShowingUnmatchedItems(bool show);
/**
* Sets up new filter string and filters the list.
*/
void setFilterSubString(const std::string& filter_str);
std::string getFilterSubString() const { return mFilterSubString; }
/**
* Filters the list, rearranges and notifies parent about shape changes.
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
*/
void filterItems();
/**
* Returns true if last call of filterItems() found at least one matching item
*/
bool hasMatchedItems();
protected:
LLFlatListViewEx(const Params& p);
/**
* Applies a message for empty list depend on passed argument.
*
* @param filter_string - if is not empty, message for filtered items will be set, otherwise for
* completely empty list. Value of filter string will be passed as search_term in SLURL.
*/
void updateNoItemsMessage(const std::string& filter_string);
/**
* Applies visibility acording to action and LLFlatListView settings.
*
* @param item - item we are changing
* @param item - action - parameters to determin visibility from
*/
void updateItemVisibility(LLPanel* item, const LLSD &action);
private:
std::string mNoFilteredItemsMsg;
std::string mNoItemsMsg;
std::string mFilterSubString;
/**
* Show list items that don't match current filter
*/
bool mForceShowingUnmatchedItems;
/**
* True if last call of filterItems() found at least one matching item
*/
bool mHasMatchedItems;
};
#endif

View File

@@ -2,31 +2,25 @@
* @file llscrollbar.cpp
* @brief Scrollbar UI widget
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -46,6 +40,7 @@
#include "llwindow.h"
#include "llcontrol.h"
#include "llrender.h"
#include "lluictrlfactory.h"
LLScrollbar::LLScrollbar(
const std::string& name, LLRect rect,
@@ -402,7 +397,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
}
getWindow()->setCursor(UI_CURSOR_ARROW);
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (active)" << LL_ENDL;
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (active)" << LL_ENDL;
handled = TRUE;
}
else
@@ -414,7 +409,7 @@ BOOL LLScrollbar::handleHover(S32 x, S32 y, MASK mask)
if( !handled )
{
getWindow()->setCursor(UI_CURSOR_ARROW);
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL;
LL_DEBUGS("UserInput") << "hover handled by " << getName() << " (inactive)" << LL_ENDL;
handled = TRUE;
}
@@ -468,6 +463,13 @@ BOOL LLScrollbar::handleMouseUp(S32 x, S32 y, MASK mask)
return handled;
}
BOOL LLScrollbar::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// just treat a double click as a second click
return handleMouseDown(x, y, mask);
}
void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
{
if (width == getRect().getWidth() && height == getRect().getHeight()) return;
@@ -509,7 +511,6 @@ void LLScrollbar::draw()
mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLSmoothInterpolation::getInterpolant(0.05f));
}
// Draw background and thumb.
LLUIImage* rounded_rect_imagep = LLUI::getUIImage("Rounded_Square");
@@ -525,6 +526,9 @@ void LLScrollbar::draw()
}
else
{
// Thumb
LLRect outline_rect = mThumbRect;
outline_rect.stretch(2);
// Background
rounded_rect_imagep->drawSolid(mOrientation == HORIZONTAL ? SCROLLBAR_SIZE : 0,
mOrientation == VERTICAL ? SCROLLBAR_SIZE : 0,
@@ -532,9 +536,6 @@ void LLScrollbar::draw()
mOrientation == VERTICAL ? getRect().getHeight() - 2 * SCROLLBAR_SIZE : getRect().getHeight(),
mTrackColor);
// Thumb
LLRect outline_rect = mThumbRect;
outline_rect.stretch(2);
if (gFocusMgr.getKeyboardFocus() == this)
{
@@ -636,3 +637,8 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
{
changeLine( mStepSize, TRUE );
}
void LLScrollbar::setThickness(S32 thickness)
{
mThickness = thickness < 0 ? SCROLLBAR_SIZE : thickness;
}

View File

@@ -2,31 +2,25 @@
* @file llscrollbar.h
* @brief Scrollbar UI widget
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/
@@ -36,6 +30,7 @@
#include "stdtypes.h"
#include "lluictrl.h"
#include "v4color.h"
#include "llbutton.h"
//
// Constants
@@ -59,6 +54,7 @@ public:
callback_t change_callback,
S32 step_size = 1);
public:
virtual ~LLScrollbar();
virtual void setValue(const LLSD& value);
@@ -67,6 +63,7 @@ public:
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -104,6 +101,9 @@ public:
void onLineUpBtnPressed(const LLSD& data);
void onLineDownBtnPressed(const LLSD& data);
S32 getThickness() const { return mThickness; }
void setThickness(S32 thickness);
void setTrackColor( const LLColor4& color ) { mTrackColor = color; }
void setThumbColor( const LLColor4& color ) { mThumbColor = color; }
void setHighlightColor( const LLColor4& color ) { mHighlightColor = color; }
@@ -145,5 +145,4 @@ private:
};
#endif // LL_SCROLLBAR_H

View File

@@ -218,6 +218,15 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
return FALSE;
}
BOOL LLScrollContainer::handleUnicodeCharHere(llwchar uni_char)
{
if (mScrolledView && mScrolledView->handleUnicodeCharHere(uni_char))
{
return TRUE;
}
return FALSE;
}
BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
// Give event to my child views - they may have scroll bars
@@ -262,7 +271,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
//S32 scrollbar_size = SCROLLBAR_SIZE;
// Scroll folder view if needed. Never accepts a drag or drop.
*accept = ACCEPT_NO;
BOOL handled = autoScroll(x, y);
@@ -413,6 +421,7 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
}
}
void LLScrollContainer::draw()
{
S32 scrollbar_size = SCROLLBAR_SIZE;
@@ -525,7 +534,7 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group)
void LLScrollContainer::updateScroll()
{
if (!mScrolledView)
if (!getVisible() || !mScrolledView)
{
return;
}
@@ -626,6 +635,7 @@ LLRect LLScrollContainer::getVisibleContentRect()
visible_rect.translate(-contents_rect.mLeft, -contents_rect.mBottom);
return visible_rect;
}
LLRect LLScrollContainer::getContentWindowRect()
{
updateScroll();
@@ -729,6 +739,13 @@ S32 LLScrollContainer::getBorderWidth() const
return 0;
}
void LLScrollContainer::setSize(S32 size)
{
mSize = size;
mScrollbar[VERTICAL]->setThickness(size);
mScrollbar[HORIZONTAL]->setThickness(size);
}
// virtual
LLXMLNodePtr LLScrollContainer::getXML(bool save_children) const
{

View File

@@ -2,31 +2,25 @@
* @file llscrollcontainer.h
* @brief LLScrollContainer class header file.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/
@@ -78,7 +72,7 @@ public:
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
LLRect getVisibleContentRect();
LLRect getContentWindowRect();
const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
virtual const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
void pageUp(S32 overlap = 0);
void pageDown(S32 overlap = 0);
void goToTop();
@@ -90,6 +84,7 @@ public:
// LLView functionality
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual BOOL handleUnicodeCharHere(llwchar uni_char);
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
@@ -105,9 +100,14 @@ public:
virtual LLXMLNodePtr getXML(bool save_children) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
S32 getSize() const { return mSize; }
void setSize(S32 thickness);
protected:
LLView* mScrolledView;
private:
void init();
// internal scrollbar handlers
virtual void scrollHorizontal( S32 new_pos );
virtual void scrollVertical( S32 new_pos );
@@ -117,7 +117,6 @@ public:
private:
LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
LLView* mScrolledView;
S32 mSize;
BOOL mIsOpaque;
LLColor4 mBackgroundColor;

View File

@@ -1896,3 +1896,8 @@ void LLTabContainer::commitHoveredButton(S32 x, S32 y)
}
}
S32 LLTabContainer::getTotalTabWidth() const
{
return mTotalTabWidth;
}

View File

@@ -98,6 +98,7 @@ public:
S32 getIndexForPanel(LLPanel* panel);
S32 getPanelIndexByTitle(const std::string& title);
LLPanel* getPanelByName(const std::string& name);
S32 getTotalTabWidth() const;
void setCurrentTabName(const std::string& name);
void selectFirstTab();

View File

@@ -387,6 +387,7 @@ static LFIDBearer::Type get_type_from_url(const std::string& url)
auto type = url.substr(pos + 5, 5);
return type == "agent" ? LFIDBearer::AVATAR
: type == "group" ? LFIDBearer::GROUP
: type == "experience" ? LFIDBearer::EXPERIENCE
: LFIDBearer::OBJECT;
}
return LFIDBearer::NONE;
@@ -4990,110 +4991,6 @@ void LLTextEditor::setOnScrollEndCallback(void (*callback)(void*), void* userdat
mScrollbar->setOnScrollEndCallback(callback, userdata);
}
///////////////////////////////////////////////////////////////////
// Hack for Notecards
BOOL LLTextEditor::importBuffer(const char* buffer, S32 length )
{
std::istringstream instream(buffer);
// Version 1 format:
// Linden text version 1\n
// {\n
// <EmbeddedItemList chunk>
// Text length <bytes without \0>\n
// <text without \0> (text may contain ext_char_values)
// }\n
char tbuf[MAX_STRING]; /* Flawfinder: ignore */
S32 version = 0;
instream.getline(tbuf, MAX_STRING);
if( 1 != sscanf(tbuf, "Linden text version %d", &version) )
{
LL_WARNS() << "Invalid Linden text file header " << LL_ENDL;
return FALSE;
}
if( 1 != version )
{
LL_WARNS() << "Invalid Linden text file version: " << version << LL_ENDL;
return FALSE;
}
instream.getline(tbuf, MAX_STRING);
if( 0 != sscanf(tbuf, "{") )
{
LL_WARNS() << "Invalid Linden text file format" << LL_ENDL;
return FALSE;
}
S32 text_len = 0;
instream.getline(tbuf, MAX_STRING);
if( 1 != sscanf(tbuf, "Text length %d", &text_len) )
{
LL_WARNS() << "Invalid Linden text length field" << LL_ENDL;
return FALSE;
}
if( text_len > mMaxTextByteLength )
{
LL_WARNS() << "Invalid Linden text length: " << text_len << LL_ENDL;
return FALSE;
}
BOOL success = TRUE;
char* text = new char[ text_len + 1];
if (text == NULL)
{
LL_ERRS() << "Memory allocation failure." << LL_ENDL;
return FALSE;
}
instream.get(text, text_len + 1, '\0');
text[text_len] = '\0';
if( text_len != (S32)strlen(text) )/* Flawfinder: ignore */
{
LL_WARNS() << llformat("Invalid text length: %d != %d ",strlen(text),text_len) << LL_ENDL;/* Flawfinder: ignore */
success = FALSE;
}
instream.getline(tbuf, MAX_STRING);
if( success && (0 != sscanf(tbuf, "}")) )
{
LL_WARNS() << "Invalid Linden text file format: missing terminal }" << LL_ENDL;
success = FALSE;
}
if( success )
{
// Actually set the text
setText( LLStringExplicit(text) );
}
delete[] text;
setCursorPos(0);
deselect();
needsReflow();
return success;
}
BOOL LLTextEditor::exportBuffer(std::string &buffer )
{
std::ostringstream outstream(buffer);
outstream << "Linden text version 1\n";
outstream << "{\n";
outstream << llformat("Text length %d\n", mWText.length() );
outstream << getText();
outstream << "}\n";
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// LLTextSegment

View File

@@ -236,8 +236,8 @@ public:
void setCommitOnFocusLost(BOOL b) { mCommitOnFocusLost = b; }
// Hack to handle Notecards
virtual BOOL importBuffer(const char* buffer, S32 length );
virtual BOOL exportBuffer(std::string& buffer );
virtual BOOL importBuffer(const char* buffer, S32 length) { return false; }
virtual BOOL exportBuffer(std::string& buffer) { return false; }
// If takes focus, will take keyboard focus on click.
void setTakesFocus(BOOL b) { mTakesFocus = b; }

View File

@@ -38,6 +38,7 @@
#include "lltrans.h"
//#include "lluicolortable.h"
#include "message.h"
#include "llexperiencecache.h"
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp> // <alchemy/>
@@ -587,7 +588,7 @@ void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
}
mAvatarNameCacheConnections.erase(range.first, range.second);
std::string label = av_name.getCompleteName();
std::string label = av_name.getNSName();
// received the agent name from the server - tell our observers
callObservers(id.asString(), label, mIcon);
@@ -665,7 +666,7 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
LLAvatarName av_name;
if (LLAvatarNameCache::get(agent_id, &av_name))
{
std::string label = av_name.getCompleteName();
std::string label = av_name.getNSName();
// handle suffixes like /mute or /offerteleport
label = localize_slapp_label(url, label);
@@ -1492,13 +1493,65 @@ std::string LLUrlEntryEmail::getUrl(const std::string &string) const
return escapeUrl(string);
}
LLUrlEntryExperienceProfile::LLUrlEntryExperienceProfile()
{
mPattern = boost::regex(APP_HEADER_REGEX "/experience/[\\da-f-]+/\\w+\\S*",
boost::regex::perl|boost::regex::icase);
mIcon = "Generic_Experience";
mMenuName = "menu_url_experience.xml";
}
std::string LLUrlEntryExperienceProfile::getLabel(const std::string& url, const LLUrlLabelCallback& cb)
{
if (!gCacheName)
{
// probably at the login screen, use short string for layout
return LLTrans::getString("LoadingData");
}
std::string experience_id_string = getIDStringFromUrl(url);
if (experience_id_string.empty())
{
// something went wrong, just give raw url
return unescapeUrl(url);
}
LLUUID experience_id(experience_id_string);
if (experience_id.isNull())
{
return LLTrans::getString("ExperienceNameNull");
}
const LLSD& experience_details = LLExperienceCache::instance().get(experience_id);
if (!experience_details.isUndefined())
{
std::string experience_name_string = experience_details[LLExperienceCache::NAME].asString();
return experience_name_string.empty() ? LLTrans::getString("ExperienceNameUntitled") : experience_name_string;
}
addObserver(experience_id_string, url, cb);
LLExperienceCache::instance().get(experience_id, boost::bind(&LLUrlEntryExperienceProfile::onExperienceDetails, this, _1));
return LLTrans::getString("LoadingData");
}
void LLUrlEntryExperienceProfile::onExperienceDetails(const LLSD& experience_details)
{
std::string name = experience_details[LLExperienceCache::NAME].asString();
if(name.empty())
{
name = LLTrans::getString("ExperienceNameUntitled");
}
callObservers(experience_details[LLExperienceCache::EXPERIENCE_ID].asString(), name, LLStringUtil::null);
}
// <alchemy>
//
// LLUrlEntryJIRA describes a Jira Issue Tracker entry
//
LLUrlEntryJira::LLUrlEntryJira()
{
mPattern = boost::regex("((?:ALCH|SV|BUG|CHOP|FIRE|MAINT|OPEN|SCR|STORM|SVC|VWR|WEB)-\\d+)",
mPattern = boost::regex("(\\b(?:ALCH|SV|BUG|CHOP|FIRE|MAINT|OPEN|SCR|STORM|SVC|VWR|WEB)-\\d+)",
boost::regex::perl);
mMenuName = "menu_url_http.xml";
mTooltip = LLTrans::getString("TooltipHttpUrl");
@@ -1522,7 +1575,7 @@ std::string LLUrlEntryJira::getUrl(const std::string &url) const
(url.find("SV") != std::string::npos) ?
"https://singularityviewer.atlassian.net/browse/%1%" :
(url.find("FIRE") != std::string::npos) ?
"http://jira.phoenixviewer.com/browse/%1%" :
"https://jira.firestormviewer.com/browse/%1%" :
"http://jira.secondlife.com/browse/%1%"
) % url).str();
}

View File

@@ -132,7 +132,7 @@ protected:
///
/// LLUrlEntryHTTP Describes generic http: and https: Urls
///
class LLUrlEntryHTTP : public LLUrlEntryBase
class LLUrlEntryHTTP final : public LLUrlEntryBase
{
public:
LLUrlEntryHTTP();
@@ -144,7 +144,7 @@ public:
///
/// LLUrlEntryHTTPLabel Describes generic http: and https: Urls with custom labels
///
class LLUrlEntryHTTPLabel : public LLUrlEntryBase
class LLUrlEntryHTTPLabel final : public LLUrlEntryBase
{
public:
LLUrlEntryHTTPLabel();
@@ -156,7 +156,7 @@ public:
///
/// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com
///
class LLUrlEntryHTTPNoProtocol : public LLUrlEntryBase
class LLUrlEntryHTTPNoProtocol final : public LLUrlEntryBase
{
public:
LLUrlEntryHTTPNoProtocol();
@@ -166,7 +166,7 @@ public:
std::string getTooltip(const std::string &url) const override;
};
class LLUrlEntryInvalidSLURL : public LLUrlEntryBase
class LLUrlEntryInvalidSLURL final : public LLUrlEntryBase
{
public:
LLUrlEntryInvalidSLURL();
@@ -180,7 +180,7 @@ public:
///
/// LLUrlEntrySLURL Describes http://slurl.com/... Urls
///
class LLUrlEntrySLURL : public LLUrlEntryBase
class LLUrlEntrySLURL final : public LLUrlEntryBase
{
public:
LLUrlEntrySLURL();
@@ -205,7 +205,7 @@ public:
///
/// LLUrlEntrySeconlifeURLs Describes *secondlife.com and *lindenlab.com Urls
///
class LLUrlEntrySimpleSecondlifeURL : public LLUrlEntrySecondlifeURL
class LLUrlEntrySimpleSecondlifeURL final : public LLUrlEntrySecondlifeURL
{
public:
LLUrlEntrySimpleSecondlifeURL();
@@ -281,7 +281,7 @@ private:
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
/// that displays the full display name + user name for an avatar
/// such as "James Linden (james.linden)"
class LLUrlEntryAgentCompleteName : public LLUrlEntryAgentName
class LLUrlEntryAgentCompleteName final : public LLUrlEntryAgentName
{
public:
LLUrlEntryAgentCompleteName();
@@ -289,7 +289,7 @@ private:
/*virtual*/ std::string getName(const LLAvatarName& avatar_name) override;
};
class LLUrlEntryAgentLegacyName : public LLUrlEntryAgentName
class LLUrlEntryAgentLegacyName final : public LLUrlEntryAgentName
{
public:
LLUrlEntryAgentLegacyName();
@@ -302,7 +302,7 @@ private:
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
/// that displays the just the display name for an avatar
/// such as "James Linden"
class LLUrlEntryAgentDisplayName : public LLUrlEntryAgentName
class LLUrlEntryAgentDisplayName final : public LLUrlEntryAgentName
{
public:
LLUrlEntryAgentDisplayName();
@@ -315,7 +315,7 @@ private:
/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
/// that displays the just the display name for an avatar
/// such as "james.linden"
class LLUrlEntryAgentUserName : public LLUrlEntryAgentName
class LLUrlEntryAgentUserName final : public LLUrlEntryAgentName
{
public:
LLUrlEntryAgentUserName();
@@ -323,11 +323,25 @@ private:
/*virtual*/ std::string getName(const LLAvatarName& avatar_name) override;
};
///
/// LLUrlEntryExperienceProfile Describes a Second Life experience profile Url, e.g.,
/// secondlife:///app/experience/0e346d8b-4433-4d66-a6b0-fd37083abc4c/profile
/// that displays the experience name
class LLUrlEntryExperienceProfile final : public LLUrlEntryBase
{
public:
LLUrlEntryExperienceProfile();
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
private:
void onExperienceDetails(const LLSD& experience_details);
};
///
/// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
/// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
///
class LLUrlEntryGroup : public LLUrlEntryBase
class LLUrlEntryGroup final : public LLUrlEntryBase
{
public:
LLUrlEntryGroup();
@@ -342,7 +356,7 @@ private:
/// LLUrlEntryInventory Describes a Second Life inventory Url, e.g.,
/// secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select
///
class LLUrlEntryInventory : public LLUrlEntryBase
class LLUrlEntryInventory final : public LLUrlEntryBase
{
public:
LLUrlEntryInventory();
@@ -354,7 +368,7 @@ private:
/// LLUrlEntryObjectIM Describes a Second Life inspector for the object Url, e.g.,
/// secondlife:///app/objectim/7bcd7864-da6b-e43f-4486-91d28a28d95b?name=Object&owner=3de548e1-57be-cfea-2b78-83ae3ad95998&slurl=Danger!%20Danger!/200/200/30/&groupowned=1
///
class LLUrlEntryObjectIM : public LLUrlEntryBase
class LLUrlEntryObjectIM final : public LLUrlEntryBase
{
public:
LLUrlEntryObjectIM();
@@ -367,7 +381,7 @@ private:
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
///
class LLUrlEntryParcel : public LLUrlEntryBase
class LLUrlEntryParcel final : public LLUrlEntryBase
{
public:
struct LLParcelData
@@ -414,7 +428,7 @@ private:
/// LLUrlEntryPlace Describes a Second Life location Url, e.g.,
/// secondlife://Ahern/50/50/50
///
class LLUrlEntryPlace : public LLUrlEntryBase
class LLUrlEntryPlace final : public LLUrlEntryBase
{
public:
LLUrlEntryPlace();
@@ -426,7 +440,7 @@ public:
/// LLUrlEntryRegion Describes a Second Life location Url, e.g.,
/// secondlife:///app/region/Ahern/128/128/0
///
class LLUrlEntryRegion : public LLUrlEntryBase
class LLUrlEntryRegion final : public LLUrlEntryBase
{
public:
LLUrlEntryRegion();
@@ -438,7 +452,7 @@ public:
/// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
/// secondlife:///app/teleport/Ahern/50/50/50/
///
class LLUrlEntryTeleport : public LLUrlEntryBase
class LLUrlEntryTeleport final : public LLUrlEntryBase
{
public:
LLUrlEntryTeleport();
@@ -450,7 +464,7 @@ public:
/// LLUrlEntrySL Describes a generic SLURL, e.g., a Url that starts
/// with secondlife:// (used as a catch-all for cases not matched above)
///
class LLUrlEntrySL : public LLUrlEntryBase
class LLUrlEntrySL final : public LLUrlEntryBase
{
public:
LLUrlEntrySL();
@@ -461,7 +475,7 @@ public:
/// LLUrlEntrySLLabel Describes a generic SLURL, e.g., a Url that starts
/// with secondlife:// with the ability to specify a custom label.
///
class LLUrlEntrySLLabel : public LLUrlEntryBase
class LLUrlEntrySLLabel final : public LLUrlEntryBase
{
public:
LLUrlEntrySLLabel();
@@ -475,7 +489,7 @@ public:
/// LLUrlEntryWorldMap Describes a Second Life worldmap Url, e.g.,
/// secondlife:///app/worldmap/Ahern/50/50/50
///
class LLUrlEntryWorldMap : public LLUrlEntryBase
class LLUrlEntryWorldMap final : public LLUrlEntryBase
{
public:
LLUrlEntryWorldMap();
@@ -486,7 +500,7 @@ public:
///
/// LLUrlEntryNoLink lets us turn of URL detection with <nolink>...</nolink> tags
///
class LLUrlEntryNoLink : public LLUrlEntryBase
class LLUrlEntryNoLink final : public LLUrlEntryBase
{
public:
LLUrlEntryNoLink();
@@ -498,7 +512,7 @@ public:
///
/// LLUrlEntryIcon describes an icon with <icon>...</icon> tags
///
class LLUrlEntryIcon : public LLUrlEntryBase
class LLUrlEntryIcon final : public LLUrlEntryBase
{
public:
LLUrlEntryIcon();
@@ -510,7 +524,7 @@ public:
///
/// LLUrlEntryEmail Describes a generic mailto: Urls
///
class LLUrlEntryEmail : public LLUrlEntryBase
class LLUrlEntryEmail final : public LLUrlEntryBase
{
public:
LLUrlEntryEmail();
@@ -522,7 +536,7 @@ public:
///
/// LLUrlEntryJira describes a Jira Issue
///
class LLUrlEntryJira : public LLUrlEntryBase
class LLUrlEntryJira final : public LLUrlEntryBase
{
public:
LLUrlEntryJira();

View File

@@ -73,6 +73,7 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntryInventory());
registerUrl(new LLUrlEntryExperienceProfile());
//LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern,
//so it should be registered in the end of list
registerUrl(new LLUrlEntrySL());

View File

@@ -235,7 +235,7 @@ private:
private:
// widgets in general are not copyable
LLView(const LLView& other) {};
LLView(const LLView& other) = delete;
public:
#if LL_DEBUG
static BOOL sIsDrawing;

View File

@@ -355,6 +355,10 @@ typedef enum e_lscript_state_event_type
LSTT_REMOTE_DATA,
LSTT_HTTP_RESPONSE,
LSTT_HTTP_REQUEST,
LSTT_EXPERMISSIONS,
LSTT_TRANSACTION_RESULT,
LSTT_PATH_UPDATE,
LSTT_EXPERMISSIONS_DENIED,
LSTT_EOF,
LSTT_STATE_BEGIN = LSTT_STATE_ENTRY,
@@ -397,7 +401,11 @@ const U64 LSCRIPTStateBitField[LSTT_EOF] =
0x0000000040000000, // LSTT_OBJECT_REZ
0x0000000080000000, // LSTT_REMOTE_DATA
0x0000000100000000LL, // LSTT_HTTP_RESPOSE
0x0000000200000000LL // LSTT_HTTP_REQUEST
0x0000000200000000LL, // LSTT_HTTP_REQUEST
0x0000000400000000LL, // LSTT_EXPERMISSIONS
0x0000000800000000LL, // LSTT_TRANSACTION_RESULT
0x0000001000000000LL, // LSTT_PATH_UPDATE
0x0000002000000000LL, //LSTT_EXPERMISSIONS_DENIED
};
inline S32 get_event_handler_jump_position(U64 bit_field, LSCRIPTStateEventType type)
@@ -511,6 +519,7 @@ typedef enum e_lscript_runtime_faults
LSRF_TOO_MANY_LISTENS,
LSRF_NESTING_LISTS,
LSRF_CLI,
LSRF_INVALID_STATE,
LSRF_EOF
} LSCRIPTRunTimeFaults;
@@ -551,10 +560,10 @@ const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] =
(0x1 << 10),// SCRIPT_PERMISSION_TRACK_CAMERA
(0x1 << 11),// SCRIPT_PERMISSION_CONTROL_CAMERA
(0x1 << 12),// SCRIPT_PERMISSION_TELEPORT
(0x1 << 13),// SCRIPT_PERMISSION_EXPERIENCE,
(0x1 << 14),// SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT,
(0x1 << 15),// SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS,
(0x1 << 16),// SCRIPT_PERMISSION_RETURN_OBJECTS,
(0x1 << 13),// SCRIPT_PERMISSION_EXPERIENCE
(0x1 << 14),// SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT
(0x1 << 15),// SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS
(0x1 << 16),// SCRIPT_PERMISSION_RETURN_OBJECTS
};
// http_request string constants

View File

@@ -685,6 +685,23 @@ void parse_string();
"STATUS_INTERNAL_ERROR" { count(); yylval.ival = LSL_STATUS_INTERNAL_ERROR; return(INTEGER_CONSTANT); }
"STATUS_WHITELIST_FAILED" { count(); yylval.ival = LSL_STATUS_WHITELIST_FAILED; return(INTEGER_CONSTANT); }
"XP_ERROR_NONE" { const char* sval= "no error"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_THROTTLED" { const char* sval= "exceeded throttle"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_EXPERIENCES_DISABLED" { const char* sval= "experiences are disabled"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_INVALID_PARAMETERS" { const char* sval= "invalid parameters"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_NOT_PERMITTED" { const char* sval= "operation not permitted"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_NO_EXPERIENCE" { const char* sval= "script not associated with an experience";yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_NOT_FOUND" { const char* sval= "not found"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_INVALID_EXPERIENCE" { const char* sval= "invalid experience"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_EXPERIENCE_DISABLED" { const char* sval= "experience is disabled"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_EXPERIENCE_SUSPENDED" { const char* sval= "experience is suspended"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_UNKNOWN_ERROR" { const char* sval= "unknown error"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_QUOTA_EXCEEDED" { const char* sval= "experience data quota exceeded"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_STORE_DISABLED" { const char* sval= "key-value store is disabled"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_STORAGE_EXCEPTION" { const char* sval= "key-value store communication failed"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_KEY_NOT_FOUND" { const char* sval= "key doesn't exist"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"XP_ERROR_RETRY_UPDATE" { const char* sval= "retry update"; yylval.sval = new char[strlen(sval)+1]; strcpy(yylval.sval, sval); return(STRING_CONSTANT); }
"PROFILE_SCRIPT_NONE" { count(); yylval.ival = LSL_PROFILE_SCRIPT_NONE; return(INTEGER_CONSTANT); }
"PROFILE_SCRIPT_MEMORY" { count(); yylval.ival = LSL_PROFILE_SCRIPT_MEMORY; return(INTEGER_CONSTANT); }

View File

@@ -179,6 +179,8 @@
%type <event> money
%type <event> email
%type <event> run_time_permissions
%type <event> experience_permissions
%type <event> experience_permissions_denied
%type <event> inventory
%type <event> attach
%type <event> dataserver
@@ -787,6 +789,16 @@ event
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
gAllocationManager->addAllocation($$);
}
| experience_permissions compound_statement
{
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
gAllocationManager->addAllocation($$);
}
| experience_permissions_denied compound_statement
{
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
gAllocationManager->addAllocation($$);
}
| inventory compound_statement
{
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
@@ -1039,6 +1051,28 @@ run_time_permissions
}
;
experience_permissions
: EXPERIENCE_PERMISSIONS '(' LLKEY IDENTIFIER ')'
{
LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
gAllocationManager->addAllocation(id1);
$$ = new LLScriptEXPEvent(gLine, gColumn, id1);
gAllocationManager->addAllocation($$);
}
;
experience_permissions_denied
: EXPERIENCE_PERMISSIONS_DENIED '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ')'
{
LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
gAllocationManager->addAllocation(id1);
LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
gAllocationManager->addAllocation(id2);
$$ = new LLScriptEXPDeniedEvent(gLine, gColumn, id1, id2);
gAllocationManager->addAllocation($$);
}
;
inventory
: INVENTORY '(' INTEGER IDENTIFIER ')'
{

View File

@@ -3712,6 +3712,155 @@ S32 LLScriptNoSensorEvent::getSize()
return 0;
}
void LLScriptEXPEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
{
return;
}
switch(pass)
{
case LSCP_PRETTY_PRINT:
case LSCP_EMIT_ASSEMBLY:
fdotabs(fp, tabs, tabsize);
fprintf(fp, "experience_permissions( key ");
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
checkForDuplicateHandler(fp, this, scope, "experience_permissions");
if (scope->checkEntry(mName->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
}
else
{
mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
}
break;
case LSCP_RESOURCE:
{
// we're just tryng to determine how much space the variable needs
if (mName->mScopeEntry)
{
mName->mScopeEntry->mOffset = (S32)count;
mName->mScopeEntry->mSize = 4;
count += mName->mScopeEntry->mSize;
}
}
break;
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "experience_permissions";
chunk->addBytes(name, strlen(name) + 1);
chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
#endif
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
fdotabs(fp, tabs, tabsize);
fprintf(fp, "experience_permissions( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, " )");
break;
default:
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
}
}
S32 LLScriptEXPEvent::getSize()
{
// key = 4
return 4;
}
void LLScriptEXPDeniedEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
{
return;
}
switch(pass)
{
case LSCP_PRETTY_PRINT:
case LSCP_EMIT_ASSEMBLY:
fdotabs(fp, tabs, tabsize);
fprintf(fp, "experience_permissions_denied( key ");
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", integer ");
mReason->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
checkForDuplicateHandler(fp, this, scope, "experience_permissions_denied");
if (scope->checkEntry(mName->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
}
else
{
mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
}
if (scope->checkEntry(mReason->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
}
else
{
mReason->mScopeEntry = scope->addEntry(mReason->mName, LIT_VARIABLE, LST_INTEGER);
}
break;
case LSCP_RESOURCE:
{
// we're just trying to determine how much space the variable needs
if (mName->mScopeEntry)
{
mName->mScopeEntry->mOffset = (S32)count;
mName->mScopeEntry->mSize = 4;
count += mName->mScopeEntry->mSize;
mReason->mScopeEntry->mOffset = (S32)count;
mReason->mScopeEntry->mSize = 4;
count += mReason->mScopeEntry->mSize;
}
}
break;
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "experience_permissions_denied";
chunk->addBytes(name, strlen(name) + 1);
chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
chunk->addBytes(mReason->mName, strlen(mReason->mName) + 1);
#endif
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
fdotabs(fp, tabs, tabsize);
fprintf(fp, "experience_permissions_denied( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", int32 ");
mReason->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, " )");
break;
default:
mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mReason->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
}
}
S32 LLScriptEXPDeniedEvent::getSize()
{
// key = 4 + integer
return LSCRIPTDataSize[LST_KEY]+LSCRIPTDataSize[LST_INTEGER];
}
void LLScriptAtTarget::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
@@ -8577,6 +8726,7 @@ void LLScriptReturn::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePa
}
}
prunearg = TRUE;
break;
case LSCP_TYPE:
// if there is a return expression, it must be promotable to the return type of the function
if (mExpression)
@@ -9775,7 +9925,13 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
mScopeEntry->mFunctionArgs.addType(LST_STRING);
mScopeEntry->mFunctionArgs.addType(LST_STRING);
break;
case LSTT_EXPERMISSIONS:
mScopeEntry->mFunctionArgs.addType(LST_KEY);
break;
case LSTT_EXPERMISSIONS_DENIED:
mScopeEntry->mFunctionArgs.addType(LST_KEY);
mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
break;
default:
break;
}

View File

@@ -633,6 +633,39 @@ public:
LLScriptIdentifier *mRTPermissions;
};
class LLScriptEXPEvent : public LLScriptEvent
{
public:
LLScriptEXPEvent(S32 line, S32 col, LLScriptIdentifier *name)
: LLScriptEvent(line, col, LSTT_EXPERMISSIONS), mName(name)
{
}
~LLScriptEXPEvent() {}
void recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
S32 getSize();
LLScriptIdentifier *mName;
};
class LLScriptEXPDeniedEvent : public LLScriptEvent
{
public:
LLScriptEXPDeniedEvent(S32 line, S32 col, LLScriptIdentifier *name, LLScriptIdentifier *reason)
: LLScriptEvent(line, col, LSTT_EXPERMISSIONS_DENIED), mName(name), mReason(reason)
{
}
~LLScriptEXPDeniedEvent() {}
void recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
S32 getSize();
LLScriptIdentifier *mName;
LLScriptIdentifier *mReason;
};
class LLScriptChatEvent : public LLScriptEvent
{
public:

View File

@@ -18,7 +18,6 @@ include(FMODSTUDIO)
include(GeneratePrecompiledHeader)
include(GLOD)
include(Hunspell)
include(Json)
include(LLAddBuildTest)
include(LLAppearance)
include(LLAudio)
@@ -63,7 +62,6 @@ include_directories(
${STATEMACHINE_INCLUDE_DIRS}
${DBUSGLIB_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
${JSON_INCLUDE_DIR}
${GLOD_INCLUDE_DIR}
${LLAUDIO_INCLUDE_DIRS}
${LLCHARACTER_INCLUDE_DIRS}
@@ -92,6 +90,7 @@ set(viewer_SOURCE_FILES
aixmllindengenepool.cpp
alfloaterregiontracker.cpp
aoremotectrl.cpp
aosystem.cpp
ascentfloatercontactgroups.cpp
ascentkeyword.cpp
ascentprefschat.cpp
@@ -119,6 +118,7 @@ set(viewer_SOURCE_FILES
llaisapi.cpp
llagent.cpp
llagentaccess.cpp
llagentbenefits.cpp
llagentcamera.cpp
llagentdata.cpp
llagentlanguage.cpp
@@ -181,6 +181,7 @@ set(viewer_SOURCE_FILES
lleventinfo.cpp
lleventnotifier.cpp
lleventpoll.cpp
llexperiencelog.cpp
llexternaleditor.cpp
llface.cpp
llfasttimerview.cpp
@@ -221,6 +222,9 @@ set(viewer_SOURCE_FILES
llfloatereditui.cpp
llfloaterenvsettings.cpp
llfloaterevent.cpp
llfloaterexperiencepicker.cpp
llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
llfloaterexploreanimations.cpp
llfloaterexploresounds.cpp
llfloaterfeed.cpp
@@ -320,6 +324,7 @@ set(viewer_SOURCE_FILES
llhudtext.cpp
llhudview.cpp
llimpanel.cpp
llimprocessing.cpp
llimview.cpp
llinventoryactions.cpp
llinventorybridge.cpp
@@ -382,11 +387,16 @@ set(viewer_SOURCE_FILES
llpaneldisplay.cpp
llpaneleditwearable.cpp
llpanelevent.cpp
llpanelexperiencelisteditor.cpp
llpanelexperiencelog.cpp
llpanelexperiencepicker.cpp
llpanelexperiences.cpp
llpanelface.cpp
llpanelgeneral.cpp
llpanelgroup.cpp
llpanelgroupbulk.cpp
llpanelgroupbulkban.cpp
llpanelgroupexperiences.cpp
llpanelgroupgeneral.cpp
llpanelgroupinvite.cpp
llpanelgrouplandmoney.cpp
@@ -626,6 +636,8 @@ set(viewer_HEADER_FILES
aixmllindengenepool.h
alfloaterregiontracker.h
aoremotectrl.h
aostate.h
aosystem.h
ascentfloatercontactgroups.h
ascentkeyword.h
ascentprefschat.h
@@ -653,6 +665,7 @@ set(viewer_HEADER_FILES
llaisapi.h
llagent.h
llagentaccess.h
llagentbenefits.h
llagentcamera.h
llagentdata.h
llagentlanguage.h
@@ -715,6 +728,7 @@ set(viewer_HEADER_FILES
lleventinfo.h
lleventnotifier.h
lleventpoll.h
llexperiencelog.h
llexternaleditor.h
llface.h
llfasttimerview.h
@@ -755,6 +769,9 @@ set(viewer_HEADER_FILES
llfloatereditui.h
llfloaterenvsettings.h
llfloaterevent.h
llfloaterexperiencepicker.h
llfloaterexperienceprofile.h
llfloaterexperiences.h
llfloaterexploreanimations.h
llfloaterexploresounds.h
llfloaterfeed.h
@@ -854,6 +871,7 @@ set(viewer_HEADER_FILES
llhudtext.h
llhudview.h
llimpanel.h
llimprocessing.h
llimview.h
llinventorybridge.h
llinventoryclipboard.h
@@ -916,12 +934,17 @@ set(viewer_HEADER_FILES
llpaneldisplay.h
llpaneleditwearable.h
llpanelevent.h
llpanelexperiencelisteditor.h
llpanelexperiencelog.h
llpanelexperiencepicker.h
llpanelexperiences.h
llpanelface.h
llpanelgeneral.h
llpanelgroup.h
llpanelgroupbulk.h
llpanelgroupbulkban.h
llpanelgroupbulkimpl.h
llpanelgroupexperiences.h
llpanelgroupgeneral.h
llpanelgroupinvite.h
llpanelgrouplandmoney.h
@@ -1685,6 +1708,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLAPPEARANCE_LIBRARIES}
absl::flat_hash_map
absl::node_hash_map
nlohmann_json::nlohmann_json
${FMT_LIBRARY}
)
@@ -1803,7 +1827,7 @@ if (DARWIN)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_webkit basic_plugin_filepicker)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef basic_plugin_filepicker)
if (PACKAGE)
add_custom_target(llpackage ALL DEPENDS ${VIEWER_BINARY_NAME})

View File

@@ -14,457 +14,300 @@
*/
#include "llviewerprecompiledheaders.h"
#include "NACLantispam.h"
#include "llviewercontrol.h"
#include "llnotificationsutil.h"
#include "llviewerobjectlist.h"
#include "llagent.h"
#include "llavataractions.h"
#include "llcallbacklist.h" // For idle cleaning
#include "llnotificationsutil.h"
#include "lltrans.h"
#include "llviewerobjectlist.h"
#include <time.h>
#include <boost/lexical_cast.hpp>
class NACLAntiSpamQueue
{
friend class NACLAntiSpamRegistry;
public:
const U32& getAmount() const { return mAmount; }
const U32& getTime() const { return mTime; }
protected:
NACLAntiSpamQueue(const U32& time, const U32& amount) : mTime(time), mAmount(amount) {}
void setAmount(const U32& amount) { mAmount = amount; }
void setTime(const U32& time) { mTime = time; }
void block(const LLUUID& source) { mEntries[source.asString()].block(); }
void reset() { mEntries.clear(); }
// Returns 0 if unblocked/disabled, 1 if check results in a new block, 2 if by an existing block
U8 check(const LLUUID& source, const U32& multiplier)
{
const auto key = source.asString();
auto it = mEntries.find(key);
if (it != mEntries.end())
return it->second.blockIfNeeded(mAmount * multiplier, mTime);
mEntries[key]; // Default construct an Entry
return 0U;
}
void idle()
{
// Clean out old unblocked entries
const auto time_limit = mTime + 1; // One second after time has gone up, the next offense would reset anyway
for (auto it = mEntries.begin(); it != mEntries.end();)
{
const auto& entry = it->second;
if (entry.getBlocked() || entry.withinBlockTime(time_limit))
++it;
else it = mEntries.erase(it);
}
}
private:
class Entry
{
friend class NACLAntiSpamQueue;
protected:
void reset() { updateTime(); mAmount = 1; mBlocked = false; }
const U32& getAmount() const { return mAmount; }
const std::time_t& getTime() const { return mTime; }
void updateTime() { mTime = time(nullptr); }
void block() { mBlocked = true; }
bool withinBlockTime(const U32& time_limit) const { return (time(nullptr) - mTime) <= time_limit; }
U8 blockIfNeeded(const U32& amount, const U32& time_limit)
{
if (mBlocked) return 2U; // Already blocked
if (withinBlockTime(time_limit))
{
if (++mAmount > amount)
{
block();
return 1U;
}
}
else reset(); // Enough time has passed to forgive or not already in list
return 0U;
}
bool getBlocked() const { return mBlocked; }
private:
U32 mAmount = 1;
std::time_t mTime = time(nullptr);
bool mBlocked = false;
};
boost::unordered_map<std::string, Entry> mEntries;
U32 mAmount, mTime;
};
bool can_block(const LLUUID& id)
{
if (id.isNull() || gAgent.getID() == id) return false; //Can't block system or self.
if (const LLViewerObject* obj = gObjectList.findObject(id)) //From an object,
return !obj->permYouOwner(); //not own object.
if (id.isNull() || gAgentID == id) return false; // Can't block system or self.
if (const LLViewerObject* obj = gObjectList.findObject(id)) // From an object,
return !obj->permYouOwner(); // not own object.
return true;
}
U32 NACLAntiSpamRegistry::globalAmount;
U32 NACLAntiSpamRegistry::globalTime;
bool NACLAntiSpamRegistry::bGlobalQueue;
NACLAntiSpamQueue* NACLAntiSpamRegistry::queues[NACLAntiSpamRegistry::QUEUE_MAX] = {0};
boost::unordered_map<std::string,NACLAntiSpamQueueEntry*> NACLAntiSpamRegistry::globalEntries;
boost::unordered_map<std::string,NACLAntiSpamQueueEntry*>::iterator NACLAntiSpamRegistry::it2;
bool is_collision_sound(const std::string& sound)
{
// The following sounds will be ignored for purposes of spam protection. They have been gathered from wiki documentation of frequent official sounds.
const std::array<const std::string, 29> COLLISION_SOUNDS = {
"dce5fdd4-afe4-4ea1-822f-dd52cac46b08",
"51011582-fbca-4580-ae9e-1a5593f094ec",
"68d62208-e257-4d0c-bbe2-20c9ea9760bb",
"75872e8c-bc39-451b-9b0b-042d7ba36cba",
"6a45ba0b-5775-4ea8-8513-26008a17f873",
"992a6d1b-8c77-40e0-9495-4098ce539694",
"2de4da5a-faf8-46be-bac6-c4d74f1e5767",
"6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d",
"14209133-4961-4acc-9649-53fc38ee1667",
"bc4a4348-cfcc-4e5e-908e-8a52a8915fe6",
"9e5c1297-6eed-40c0-825a-d9bcd86e3193",
"e534761c-1894-4b61-b20c-658a6fb68157",
"8761f73f-6cf9-4186-8aaa-0948ed002db1",
"874a26fd-142f-4173-8c5b-890cd846c74d",
"0e24a717-b97e-4b77-9c94-b59a5a88b2da",
"75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2",
"153c8bf7-fb89-4d89-b263-47e58b1b4774",
"55c3e0ce-275a-46fa-82ff-e0465f5e8703",
"24babf58-7156-4841-9a3f-761bdbb8e237",
"aca261d8-e145-4610-9e20-9eff990f2c12",
"0642fba6-5dcf-4d62-8e7b-94dbb529d117",
"25a863e8-dc42-4e8a-a357-e76422ace9b5",
"9538f37c-456e-4047-81be-6435045608d4",
"8c0f84c3-9afd-4396-b5f5-9bca2c911c20",
"be582e5d-b123-41a2-a150-454c39e961c8",
"c70141d4-ba06-41ea-bcbc-35ea81cb8335",
"7d1826f4-24c4-4aac-8c2e-eff45df37783",
"063c97d3-033a-4e9b-98d8-05c8074922cb",
"00000000-0000-0000-0000-000000000120"
};
// The following sounds will be ignored for purposes of spam protection. They have been gathered from wiki documentation of frequent official sounds.
const std::string COLLISION_SOUNDS[] ={"dce5fdd4-afe4-4ea1-822f-dd52cac46b08","51011582-fbca-4580-ae9e-1a5593f094ec","68d62208-e257-4d0c-bbe2-20c9ea9760bb","75872e8c-bc39-451b-9b0b-042d7ba36cba","6a45ba0b-5775-4ea8-8513-26008a17f873","992a6d1b-8c77-40e0-9495-4098ce539694","2de4da5a-faf8-46be-bac6-c4d74f1e5767","6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d","14209133-4961-4acc-9649-53fc38ee1667","bc4a4348-cfcc-4e5e-908e-8a52a8915fe6","9e5c1297-6eed-40c0-825a-d9bcd86e3193","e534761c-1894-4b61-b20c-658a6fb68157","8761f73f-6cf9-4186-8aaa-0948ed002db1","874a26fd-142f-4173-8c5b-890cd846c74d","0e24a717-b97e-4b77-9c94-b59a5a88b2da","75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2","153c8bf7-fb89-4d89-b263-47e58b1b4774","55c3e0ce-275a-46fa-82ff-e0465f5e8703","24babf58-7156-4841-9a3f-761bdbb8e237","aca261d8-e145-4610-9e20-9eff990f2c12","0642fba6-5dcf-4d62-8e7b-94dbb529d117","25a863e8-dc42-4e8a-a357-e76422ace9b5","9538f37c-456e-4047-81be-6435045608d4","8c0f84c3-9afd-4396-b5f5-9bca2c911c20","be582e5d-b123-41a2-a150-454c39e961c8","c70141d4-ba06-41ea-bcbc-35ea81cb8335","7d1826f4-24c4-4aac-8c2e-eff45df37783","063c97d3-033a-4e9b-98d8-05c8074922cb","00000000-0000-0000-0000-000000000120"};
const int COLLISION_SOUNDS_SIZE=29;
// NaClAntiSpamQueueEntry
NACLAntiSpamQueueEntry::NACLAntiSpamQueueEntry()
{
entryTime=0;
entryAmount=0;
blocked=false;
for (const auto& collision : COLLISION_SOUNDS)
if (collision == sound)
return true;
return false;
}
void NACLAntiSpamQueueEntry::clearEntry()
{
entryTime=0;
entryAmount=0;
blocked=false;
}
U32 NACLAntiSpamQueueEntry::getEntryAmount() const
{
return entryAmount;
}
U32 NACLAntiSpamQueueEntry::getEntryTime() const
{
return entryTime;
}
void NACLAntiSpamQueueEntry::updateEntryAmount()
{
entryAmount++;
}
void NACLAntiSpamQueueEntry::updateEntryTime()
{
entryTime=time(0);
}
void NACLAntiSpamQueueEntry::setBlocked()
{
blocked=true;
}
bool NACLAntiSpamQueueEntry::getBlocked() const
{
return blocked;
}
// NaClAntiSpamQueue
NACLAntiSpamQueue::NACLAntiSpamQueue(U32 time, U32 amount)
{
queueTime=time;
queueAmount=amount;
}
void NACLAntiSpamQueue::setAmount(U32 amount)
{
queueAmount=amount;
}
void NACLAntiSpamQueue::setTime(U32 time)
{
queueTime=time;
}
U32 NACLAntiSpamQueue::getAmount() const
{
return queueAmount;
}
U32 NACLAntiSpamQueue::getTime() const
{
return queueTime;
}
void NACLAntiSpamQueue::clearEntries()
{
for(it = entries.begin(); it != entries.end(); it++)
{
it->second->clearEntry();
}
}
void NACLAntiSpamQueue::purgeEntries()
{
for(it = entries.begin(); it != entries.end(); it++)
{
delete it->second;
}
entries.clear();
}
void NACLAntiSpamQueue::blockEntry(LLUUID& source)
{
it=entries.find(source.asString());
if(it == entries.end())
{
entries[source.asString()]=new NACLAntiSpamQueueEntry();
}
entries[source.asString()]->setBlocked();
}
int NACLAntiSpamQueue::checkEntry(LLUUID& name, U32 multiplier)
// Returns 0 if unblocked/disabled, 1 if check results in a new block, 2 if by an existing block
{
static LLCachedControl<bool> enabled(gSavedSettings,"AntiSpamEnabled",false);
if(!enabled) return 0;
it=entries.find(name.asString());
if(it != entries.end())
{
if(it->second->getBlocked()) return 2;
U32 eTime=it->second->getEntryTime();
U32 currentTime=time(0);
if((currentTime-eTime) <= queueTime)
{
it->second->updateEntryAmount();
U32 eAmount=it->second->getEntryAmount();
if(eAmount > (queueAmount*multiplier))
{
it->second->setBlocked();
return 1;
}
else
return 0;
}
else
{
it->second->clearEntry();
it->second->updateEntryAmount();
it->second->updateEntryTime();
return 0;
}
}
else
{
//LL_DEBUGS() << "[antispam] New queue entry:" << name.asString() << LL_ENDL;
entries[name.asString()]=new NACLAntiSpamQueueEntry();
entries[name.asString()]->updateEntryAmount();
entries[name.asString()]->updateEntryTime();
return 0;
}
}
// NaClAntiSpamRegistry
static const char* QUEUE_NAME[NACLAntiSpamRegistry::QUEUE_MAX] = {
"Chat",
"Inventory",
"Instant Message",
"calling card",
"sound",
"Sound Preload",
"Script Dialog",
"Teleport"};
constexpr std::array<const char*, NACLAntiSpamRegistry::QUEUE_MAX> QUEUE_NAME = {
"Chat",
"Inventory",
"Instant Message",
"calling card",
"sound",
"Sound Preload",
"Script Dialog",
"Teleport"
};
NACLAntiSpamRegistry::NACLAntiSpamRegistry(U32 time, U32 amount)
NACLAntiSpamRegistry::NACLAntiSpamRegistry()
{
globalTime=time;
globalAmount=amount;
static LLCachedControl<bool> _NACL_AntiSpamGlobalQueue(gSavedSettings,"_NACL_AntiSpamGlobalQueue");
bGlobalQueue=_NACL_AntiSpamGlobalQueue;
for(int queue = 0; queue < QUEUE_MAX; ++queue)
auto control = gSavedSettings.getControl("_NACL_AntiSpamTime");
const U32 time = control->get().asInteger();
mConnections[0] = control->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamTimeChanged, _2));
control = gSavedSettings.getControl("_NACL_AntiSpamAmount");
const U32 amount = control->get().asInteger();
mConnections[1] = control->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamAmountChanged, _2));
control = gSavedSettings.getControl("_NACL_AntiSpamGlobalQueue");
mConnections[2] = control->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamGlobalQueueChanged, _2));
initializeQueues(control->get(), time, amount);
}
void NACLAntiSpamRegistry::initializeQueues(bool global, const U32& time, const U32& amount)
{
if (global) // If Global, initialize global queue
mGlobalQueue.reset(new NACLAntiSpamQueue(time, amount));
else
{
queues[queue] = new NACLAntiSpamQueue(time,amount);
mQueues.reset(new std::array<NACLAntiSpamQueue, QUEUE_MAX>{{
NACLAntiSpamQueue(time, amount), // QUEUE_CHAT
NACLAntiSpamQueue(time, amount), // QUEUE_INVENTORY
NACLAntiSpamQueue(time, amount), // QUEUE_IM
NACLAntiSpamQueue(time, amount), // QUEUE_CALLING_CARD
NACLAntiSpamQueue(time, amount), // QUEUE_SOUND
NACLAntiSpamQueue(time, amount), // QUEUE_SOUND_PRELOAD
NACLAntiSpamQueue(time, amount), // QUEUE_SCRIPT_DIALOG
NACLAntiSpamQueue(time, amount) // QUEUE_TELEPORT
}});
}
}
//static
const char* NACLAntiSpamRegistry::getQueueName(U32 queue_id)
constexpr const char* getQueueName(const NACLAntiSpamRegistry::Type& name)
{
if(queue_id >= QUEUE_MAX)
return "Unknown";
return QUEUE_NAME[queue_id];
return name >= QUEUE_NAME.size() ? "Unknown" : QUEUE_NAME[name];
}
//static
void NACLAntiSpamRegistry::registerQueues(U32 time, U32 amount)
{
globalTime=time;
globalAmount=amount;
static LLCachedControl<bool> _NACL_AntiSpamGlobalQueue(gSavedSettings,"_NACL_AntiSpamGlobalQueue");
bGlobalQueue=_NACL_AntiSpamGlobalQueue;
for(int queue = 0; queue < QUEUE_MAX; ++queue)
{
queues[queue] = new NACLAntiSpamQueue(time,amount);
}
}
//static
/*void NACLAntiSpamRegistry::registerQueue(U32 name, U32 time, U32 amount)
{
it=queues.find(name);
if(it == queues.end())
{
queues[name]=new NACLAntiSpamQueue(time,amount);
}
}*/
//static
void NACLAntiSpamRegistry::setRegisteredQueueTime(U32 name, U32 time)
{
if(name >= QUEUE_MAX || queues[name] == 0)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to set time of antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL;
return;
}
queues[name]->setTime(time);
}
//static
void NACLAntiSpamRegistry::setRegisteredQueueAmount(U32 name, U32 amount)
{
if(name >= QUEUE_MAX || queues[name] == 0)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to set amount for antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL;
return;
}
queues[name]->setAmount(amount);
}
//static
void NACLAntiSpamRegistry::setAllQueueTimes(U32 time)
{
globalTime=time;
for(int queue = 0; queue < QUEUE_MAX; ++queue)
if( queues[queue] )
queues[queue]->setTime(time);
if (mGlobalQueue) mGlobalQueue->setTime(time);
else for(auto& queue : *mQueues) queue.setTime(time);
}
//static
void NACLAntiSpamRegistry::setAllQueueAmounts(U32 amount)
{
globalAmount=amount;
for(int queue = 0; queue < QUEUE_MAX; ++queue)
if (mGlobalQueue) mGlobalQueue->setAmount(amount);
else for (U8 queue = 0U; queue < QUEUE_MAX; ++queue)
{
if(!queues[queue]) continue;
if(queue == QUEUE_SOUND || queue == QUEUE_SOUND_PRELOAD)
queues[queue]->setAmount(amount*5);
auto& q = (*mQueues)[queue];
if (queue == QUEUE_SOUND || queue == QUEUE_SOUND_PRELOAD)
q.setAmount(amount*5);
else
queues[queue]->setAmount(amount);
q.setAmount(amount);
}
}
//static
void NACLAntiSpamRegistry::clearRegisteredQueue(U32 name)
void NACLAntiSpamRegistry::blockOnQueue(const Type& name, const LLUUID& source)
{
if(name >= QUEUE_MAX || queues[name] == 0)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to clear antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL;
return;
}
queues[name]->clearEntries();
if (name >= QUEUE_MAX)
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was outside of the reasonable range of queues. Queue: " << getQueueName(name) << LL_ENDL;
else (mGlobalQueue ? *mGlobalQueue : (*mQueues)[name]).block(source);
}
//static
void NACLAntiSpamRegistry::purgeRegisteredQueue(U32 name)
{
if(name >= QUEUE_MAX || queues[name] == 0)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to purge antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL;
return;
}
queues[name]->purgeEntries();
}
//static
void NACLAntiSpamRegistry::blockOnQueue(U32 name, LLUUID& source)
{
if(bGlobalQueue)
{
NACLAntiSpamRegistry::blockGlobalEntry(source);
}
else
{
if(name >= QUEUE_MAX || queues[name] == 0)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL;
return;
}
queues[name]->blockEntry(source);
}
}
//static
void NACLAntiSpamRegistry::blockGlobalEntry(LLUUID& source)
{
it2=globalEntries.find(source.asString());
if(it2 == globalEntries.end())
{
globalEntries[source.asString()]=new NACLAntiSpamQueueEntry();
}
globalEntries[source.asString()]->setBlocked();
}
//static
bool NACLAntiSpamRegistry::checkQueue(U32 name, LLUUID& source, U32 multiplier)
bool NACLAntiSpamRegistry::checkQueue(const Type& name, const LLUUID& source, const LFIDBearer::Type& type, const U32& multiplier)
//returns true if blocked
{
if (name >= QUEUE_MAX)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to check antispam queue that was outside of the reasonable range of queues. Queue: " << getQueueName(name) << LL_ENDL;
return false;
}
if (!can_block(source)) return false;
int result;
if(bGlobalQueue)
auto& queue = mGlobalQueue ? *mGlobalQueue : (*mQueues)[name];
const auto result = queue.check(source, multiplier);
if (!result) return false; // Safe
if (result != 2 // Not previously blocked
&& gSavedSettings.getBOOL("AntiSpamNotify")) // and Just blocked!
{
result=NACLAntiSpamRegistry::checkGlobalEntry(source,multiplier);
}
else
{
if(name >= QUEUE_MAX || queues[name] == 0)
{
LL_ERRS("AntiSpam") << "CODE BUG: Attempting to check antispam queue that was outside of the reasonable range of queues or not created. Queue: " << getQueueName(name) << LL_ENDL;
return false;
}
result=queues[name]->checkEntry(source,multiplier);
}
if(result == 0) //Safe
return false;
else if(result == 2) //Previously blocked
{
return true;
}
else //Just blocked!
{
if(gSavedSettings.getBOOL("AntiSpamNotify"))
{
LLSD args;
args["SOURCE"] = source.asString().c_str();
args["TYPE"] = LLTrans::getString(getQueueName(name));
args["AMOUNT"] = boost::lexical_cast<std::string>(multiplier * queues[name]->getAmount());
args["TIME"] = boost::lexical_cast<std::string>(queues[name]->getTime());
LLNotificationsUtil::add("AntiSpamBlock", args);
}
return true;
const std::string get_slurl_for(const LLUUID& id, const LFIDBearer::Type& type);
const auto slurl = get_slurl_for(source, type);
LLSD args;
args["SOURCE"] = slurl.empty() ? source.asString() : slurl;
args["TYPE"] = LLTrans::getString(getQueueName(name));
args["AMOUNT"] = (LLSD::Integer)(multiplier * queue.getAmount());
args["TIME"] = (LLSD::Integer)queue.getTime();
LLNotificationsUtil::add("AntiSpamBlock", args);
}
return true;
}
// Global queue stoof
//static
void NACLAntiSpamRegistry::setGlobalQueue(bool value)
void NACLAntiSpamRegistry::idle()
{
NACLAntiSpamRegistry::purgeAllQueues();
bGlobalQueue=value;
if (mGlobalQueue) mGlobalQueue->idle();
else for (auto& queue : *mQueues) queue.idle();
}
//static
void NACLAntiSpamRegistry::setGlobalAmount(U32 amount)
void NACLAntiSpamRegistry::resetQueues()
{
globalAmount=amount;
if (mGlobalQueue) mGlobalQueue->reset();
else for (auto& queue : *mQueues) queue.reset();
LL_INFOS() << "AntiSpam Queues Reset" << LL_ENDL;
}
//static
void NACLAntiSpamRegistry::setGlobalTime(U32 time)
{
globalTime=time;
}
//static
void NACLAntiSpamRegistry::clearAllQueues()
{
if(bGlobalQueue)
NACLAntiSpamRegistry::clearGlobalEntries();
else
for(int queue = 0; queue < QUEUE_MAX; ++queue)
{
if(queues[queue]) queues[queue]->clearEntries();
}
}
//static
void NACLAntiSpamRegistry::purgeAllQueues()
{
if(bGlobalQueue)
NACLAntiSpamRegistry::purgeGlobalEntries();
// Note: These resets are upon the unique_ptr, not the Queue itself!
if (mGlobalQueue)
mGlobalQueue.reset();
else
for(int queue = 0; queue < QUEUE_MAX; ++queue)
{
if(queues[queue]) queues[queue]->purgeEntries();
}
LL_INFOS() << "AntiSpam Queues Purged" << LL_ENDL;
}
//static
int NACLAntiSpamRegistry::checkGlobalEntry(LLUUID& name, U32 multiplier)
{
static LLCachedControl<bool> enabled(gSavedSettings,"AntiSpamEnabled",false);
if(!enabled) return 0;
it2=globalEntries.find(name.asString());
if(it2 != globalEntries.end())
{
if(it2->second->getBlocked()) return 2;
U32 eTime=it2->second->getEntryTime();
U32 currentTime=time(0);
if((currentTime-eTime) <= globalTime)
{
it2->second->updateEntryAmount();
U32 eAmount=it2->second->getEntryAmount();
if(eAmount > (globalAmount*multiplier))
return 1;
else
return 0;
}
else
{
it2->second->clearEntry();
it2->second->updateEntryAmount();
it2->second->updateEntryTime();
return 0;
}
}
else
{
globalEntries[name.asString()]=new NACLAntiSpamQueueEntry();
globalEntries[name.asString()]->updateEntryAmount();
globalEntries[name.asString()]->updateEntryTime();
return 0;
}
}
//static
void NACLAntiSpamRegistry::clearGlobalEntries()
{
for(it2 = globalEntries.begin(); it2 != globalEntries.end(); it2++)
{
it2->second->clearEntry();
}
}
//static
void NACLAntiSpamRegistry::purgeGlobalEntries()
{
for(it2 = globalEntries.begin(); it2 != globalEntries.end(); it2++)
{
delete it2->second;
it2->second = 0;
}
globalEntries.clear();
mQueues.reset();
}
//Handlers
//static
// Handlers
// static
void NACLAntiSpamRegistry::startup()
{
auto onAntiSpamToggle = [](const LLControlVariable*, const LLSD& value) {
if (value.asBoolean()) instance();
else deleteSingleton();
};
auto control = gSavedSettings.getControl("AntiSpamEnabled");
control->getSignal()->connect(onAntiSpamToggle);
onAntiSpamToggle(control, control->get());
}
// static
bool NACLAntiSpamRegistry::handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue)
{
setGlobalQueue(newvalue.asBoolean());
if (instanceExists())
{
auto& inst = instance();
inst.purgeAllQueues();
inst.initializeQueues(newvalue.asBoolean(), gSavedSettings.getU32("_NACL_AntiSpamTime"), gSavedSettings.getU32("_NACL_AntiSpamAmount"));
}
return true;
}
//static
bool NACLAntiSpamRegistry::handleNaclAntiSpamTimeChanged(const LLSD& newvalue)
{
setAllQueueTimes(newvalue.asInteger());
if (auto inst = getIfExists()) inst->setAllQueueTimes(newvalue.asInteger());
return true;
}
//static
bool NACLAntiSpamRegistry::handleNaclAntiSpamAmountChanged(const LLSD& newvalue)
{
setAllQueueAmounts(newvalue.asInteger());
if (auto inst = getIfExists()) inst->setAllQueueAmounts(newvalue.asInteger());
return true;
}
}

View File

@@ -13,72 +13,22 @@
* 0. You just DO WHAT THE FUCK YOU WANT TO.
*/
#ifndef NACLANTISPAM_H
#define NACLANTISPAM_H
#pragma once
#include <boost/signals2/connection.hpp>
#include <boost/unordered/unordered_map.hpp>
#include "stdtypes.h"
#include "lfidbearer.h"
#include "lluuid.h"
class NACLAntiSpamQueueEntry
class NACLAntiSpamQueue;
class NACLAntiSpamRegistry final : public LLSingleton<NACLAntiSpamRegistry>
{
friend class NACLAntiSpamQueue;
friend class NACLAntiSpamRegistry;
protected:
NACLAntiSpamQueueEntry();
void clearEntry();
U32 getEntryAmount() const;
U32 getEntryTime() const;
void updateEntryAmount();
void updateEntryTime();
bool getBlocked() const;
void setBlocked();
private:
U32 entryAmount;
U32 entryTime;
bool blocked;
};
class NACLAntiSpamQueue
{
friend class NACLAntiSpamRegistry;
friend class LLSingleton<NACLAntiSpamRegistry>;
NACLAntiSpamRegistry();
public:
U32 getAmount() const;
U32 getTime() const;
protected:
NACLAntiSpamQueue(U32 time, U32 amount);
void setAmount(U32 amount);
void setTime(U32 time);
void clearEntries();
void purgeEntries();
void blockEntry(LLUUID& source);
int checkEntry(LLUUID& source, U32 multiplier);
private:
boost::unordered_map<std::string,NACLAntiSpamQueueEntry*> entries;
boost::unordered_map<std::string,NACLAntiSpamQueueEntry*>::iterator it;
U32 queueAmount;
U32 queueTime;
};
class NACLAntiSpamRegistry
{
public:
NACLAntiSpamRegistry(U32 time=2, U32 amount=10);
static void registerQueues(U32 time=2, U32 amount=10);
// static void registerQueue(U32 name, U32 time, U32 amount);
static void setRegisteredQueueTime(U32 name, U32 time);
static void setRegisteredQueueAmount(U32 name,U32 amount);
static void setAllQueueTimes(U32 amount);
static void setAllQueueAmounts(U32 time);
static bool checkQueue(U32 name, LLUUID& source, U32 multiplier=1);
static bool handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue);
static bool handleNaclAntiSpamTimeChanged(const LLSD& newvalue);
static bool handleNaclAntiSpamAmountChanged(const LLSD& newvalue);
static void clearRegisteredQueue(U32 name);
static void purgeRegisteredQueue(U32 name);
static void clearAllQueues();
static void purgeAllQueues();
static void setGlobalQueue(bool value);
static void setGlobalAmount(U32 amount);
static void setGlobalTime(U32 time);
static void blockOnQueue(U32 name,LLUUID& owner_id);
enum {
static void startup();
enum Type : U8 {
QUEUE_CHAT,
QUEUE_INVENTORY,
QUEUE_IM,
@@ -89,22 +39,19 @@ public:
QUEUE_TELEPORT,
QUEUE_MAX
};
bool checkQueue(const Type& name, const LLUUID& source, const LFIDBearer::Type& type = LFIDBearer::AVATAR, const U32& multiplier = 1);
void blockOnQueue(const Type& name, const LLUUID& owner_id);
void idle();
void resetQueues();
private:
static const char* getQueueName(U32 queue_id);
static NACLAntiSpamQueue* queues[QUEUE_MAX];
static boost::unordered_map<std::string,NACLAntiSpamQueueEntry*> globalEntries;
static boost::unordered_map<std::string,NACLAntiSpamQueueEntry*>::iterator it2;
static U32 globalTime;
static U32 globalAmount;
static bool bGlobalQueue;
static int checkGlobalEntry(LLUUID& source, U32 multiplier);
static void clearGlobalEntries();
static void purgeGlobalEntries();
static void blockGlobalEntry(LLUUID& source);
void setAllQueueTimes(U32 amount);
void setAllQueueAmounts(U32 time);
void purgeAllQueues();
void initializeQueues(bool global, const U32& time, const U32& amount);
static bool handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue);
static bool handleNaclAntiSpamTimeChanged(const LLSD& newvalue);
static bool handleNaclAntiSpamAmountChanged(const LLSD& newvalue);
std::unique_ptr<std::array<NACLAntiSpamQueue, QUEUE_MAX>> mQueues;
std::unique_ptr<NACLAntiSpamQueue> mGlobalQueue;
std::array<boost::signals2::scoped_connection, 3> mConnections;
};
extern const std::string COLLISION_SOUNDS[];
extern const int COLLISION_SOUNDS_SIZE;
#endif //NACLANTISPAM_H

View File

@@ -1 +1 @@
1.8.7
1.8.9

View File

@@ -117,6 +117,9 @@ void ALFloaterRegionTracker::refresh()
{
saved_selected_values.push_back(item->getValue().asString());
}
S32 saved_scroll_pos = mRegionScrollList->getScrollPos();
auto sort_column_name = mRegionScrollList->getSortColumnName();
auto sort_asending = mRegionScrollList->getSortAscending();
mRegionScrollList->deleteAllItems();
const std::string& cur_region_name = gAgent.getRegion()->getName();
@@ -172,8 +175,11 @@ void ALFloaterRegionTracker::refresh()
mRegionScrollList->addRow(row);
}
}
mRegionScrollList->sortByColumn(sort_column_name, sort_asending);
if (!saved_selected_values.empty())
mRegionScrollList->selectMultiple(saved_selected_values);
mRegionScrollList->setScrollPos(saved_scroll_pos);
}
BOOL ALFloaterRegionTracker::tick()

37
indra/newview/aostate.h Normal file
View File

@@ -0,0 +1,37 @@
#pragma once
enum AOState : U8
{
STATE_AGENT_IDLE,
STATE_AGENT_WALK,
STATE_AGENT_RUN,
STATE_AGENT_PRE_JUMP,
STATE_AGENT_JUMP,
STATE_AGENT_TURNLEFT,
STATE_AGENT_TURNRIGHT,
STATE_AGENT_SIT,
STATE_AGENT_SIT_GROUND,
STATE_AGENT_HOVER,
STATE_AGENT_HOVER_DOWN,
STATE_AGENT_HOVER_UP,
STATE_AGENT_CROUCH,
STATE_AGENT_CROUCHWALK,
STATE_AGENT_FALLDOWN,
STATE_AGENT_STANDUP,
STATE_AGENT_LAND,
STATE_AGENT_FLY,
STATE_AGENT_FLYSLOW,
STATE_AGENT_TYPE,
STATE_AGENT_SWIM_DOWN,
STATE_AGENT_SWIM_UP,
STATE_AGENT_SWIM,
STATE_AGENT_FLOAT,
STATE_AGENT_END
};

596
indra/newview/aosystem.cpp Normal file
View File

@@ -0,0 +1,596 @@
/**
* @file aosystem.cpp
* @brief clientside animation overrider
* by Skills Hak & Liru Færs
*/
#include "llviewerprecompiledheaders.h"
#include "aosystem.h"
#include "floaterao.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llanimationstates.h"
#include "llinventoryfunctions.h"
#include "llinventorypanel.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llmemorystream.h"
#include "llnotecard.h"
#include "llstartup.h"
#include "llvoavatarself.h"
#include "llviewerregion.h"
#include "roles_constants.h"
#include <boost/regex.hpp>
// Uncomment and use instead if we ever add the chatbar as a command line - MC
void cmdline_printchat(const std::string& message);
namespace
{
bool sSwimming = false;
bool enable_swim()
{
static const LLCachedControl<bool> swim(gSavedSettings, "AOSwimEnabled", false);
return swim;
}
bool is_underwater() { return enable_swim() && gAgentAvatarp && gAgentAvatarp->mBelowWater; }
}
// -------------------------------------------------------
void AOSystem::AOStandTimer::reset()
{
mPeriod = gSavedSettings.getF32("AOStandInterval");
mEventTimer.reset();
// LL_INFOS() << "reset" << LL_ENDL;
}
// -------------------------------------------------------
class AOInvTimer final : public LLEventTimer, public LLSingleton<AOInvTimer>
{
friend class LLSingleton<AOInvTimer>;
friend class AOSystem;
AOInvTimer() : LLEventTimer(1.0f) {}
~AOInvTimer() {}
static void createIfNeeded()
{
if (needed()) LLSingleton::getInstance();
else AOSystem::getInstance();
}
public:
static bool needed()
{
return LLStartUp::getStartupState() < STATE_INVENTORY_SEND // Haven't done inventory transfer yet
|| !LLInventoryModelBackgroundFetch::instance().isEverythingFetched(); // Everything hasn't been fetched yet
}
BOOL tick() override
{
if (!gSavedSettings.getBOOL("AOEnabled")) return true; // If disabled on a tick, we don't care anymore
if (!needed())
{
// cmdline_printchat("Inventory fetched, loading AO.");
AOSystem::getInstance(); // Initializes everything
return true;
}
return false;
}
};
class ObjectNameMatches final : public LLInventoryCollectFunctor
{
public:
ObjectNameMatches(const std::string& name, const LLUUID& folder) : mName(name), mFolder(folder) {}
virtual ~ObjectNameMatches() {}
bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override
{
return item && item->getParentUUID() == mFolder && item->getName() == mName;
}
private:
const std::string& mName;
const LLUUID& mFolder;
};
static LLUUID invfolderid;
LLUUID getAssetIDByName(const std::string& name)
{
if (name.empty()) return LLUUID::null;
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
ObjectNameMatches matches(name, invfolderid);
gInventory.collectDescendentsIf(LLUUID::null, cats, items, false, matches, true);
return items.empty() ? LLUUID(name) : items[0]->getAssetUUID();
};
void AOSystem::start()
{
llassert(!instanceExists() && !AOInvTimer::instanceExists()); // This should only be run once!
auto control(gSavedSettings.getControl("AOEnabled"));
if (control->get()) AOInvTimer::createIfNeeded(); // Start the clock
control->getSignal()->connect([](LLControlVariable*, const LLSD& enabled) {
if (enabled.asBoolean()) AOInvTimer::createIfNeeded(); // Start the clock
else deleteSingleton();
});
}
// STUFF -------------------------------------------------------
AOSystem::overrides::overrides(const char* setting_name)
: setting(setting_name ? gSavedPerAccountSettings.getControl("AODefault" + std::string(setting_name)) : nullptr)
, playing(false)
{
}
bool AOSystem::overrides::play_condition() const
{
// Stop stand first then play
instance().stopCurrentStand();
return false;
}
void AOSystem::overrides::play(bool start)
{
if (playing == start) return;
// LL_INFOS() << "st" << (start ? "art" : "op") << " override: " << aop->getOverride() << LL_ENDL;
// We can always stop, but starting is particular
if (start)
{
if (play_condition())
return;
}
else if (playing && !isLowPriority()) // Stands were turned off if this isn't a low priority overrides
{
if (!isAgentAvatarValid() && !gAgentAvatarp->isSitting() && !gAgent.getFlying()) // check if sitting or hovering
instance().stand().play();
}
playing = start;
gAgent.sendAnimationRequest(ao_id, start ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
}
struct override_low_priority final : public AOSystem::overrides
{
override_low_priority(const LLUUID& id, const char* setting_name = nullptr)
: overrides(setting_name), orig_id(id) {}
bool overrideAnim(bool swimming, const LLUUID& anim) const override { return orig_id == anim; }
bool play_condition() const override { return false; }
bool isLowPriority() const override { return true; }
private:
const LLUUID orig_id;
};
struct override_single final : public AOSystem::overrides
{
override_single(const LLUUID& id, const char* setting_name = nullptr, U8 swim = 2)
: overrides(setting_name), orig_id(id), swim(swim) {}
bool overrideAnim(bool swimming, const LLUUID& anim) const override { return (swim == 2 || !!swim == swimming) && orig_id == anim; }
private:
const LLUUID orig_id;
const U8 swim; // 2 = irrelevant, 0 = flying, 1 = swimming
};
struct override_sit final : public AOSystem::overrides
{
override_sit(const uuid_set_t& ids, const char* setting_name = nullptr)
: overrides(setting_name)
, orig_ids(ids)
{}
bool overrideAnim(bool swimming, const LLUUID& anim) const override { return orig_ids.find(anim) != orig_ids.end(); }
bool play_condition() const override
{
overrides::play_condition();
return !gSavedSettings.getBOOL("AOSitsEnabled");
}
private:
const uuid_set_t orig_ids;
};
bool AOSystem::override_stand::play_condition() const
{
// Do not call base, stands do their own thing
// stands have lowest priority
return (!isAgentAvatarValid() || gAgentAvatarp->isSitting())
&& (gAgentCamera.cameraMouselook() && gSavedSettings.getBOOL("AONoStandsInMouselook"));
}
bool AOSystem::override_stand::overrideAnim(bool swimming, const LLUUID& anim) const
{
return anim == ANIM_AGENT_STAND;
}
AOSystem::AOSystem()
: stand_iterator(0)
, mAOOverrides({})
{
// TODO: When we move to C++20 and when GCC and MSVC support it (at the time of writing, neither fully do), use __VA_OPT__ here instead.
#define ANY_OVERRIDE(which, state, ...) mAOOverrides[STATE_AGENT_##state] = new which(ANIM_AGENT_##state, ##__VA_ARGS__)
#define BASIC_OVERRIDE(state, ...) ANY_OVERRIDE(override_single, state, ##__VA_ARGS__)
mAOOverrides[STATE_AGENT_IDLE] = new override_stand();
BASIC_OVERRIDE(WALK, "Walk");
BASIC_OVERRIDE(RUN, "Run");
BASIC_OVERRIDE(PRE_JUMP, "PreJump");
BASIC_OVERRIDE(JUMP, "Jump");
BASIC_OVERRIDE(TURNLEFT);
BASIC_OVERRIDE(TURNRIGHT);
#define SIT_OVERRIDE(control, state, ...) mAOOverrides[STATE_AGENT_##state] = new override_sit(uuid_set_t{ANIM_AGENT_##state, __VA_ARGS__}, control)
SIT_OVERRIDE("Sit", SIT, ANIM_AGENT_SIT_FEMALE, ANIM_AGENT_SIT_GENERIC);
SIT_OVERRIDE("GroundSit", SIT_GROUND, ANIM_AGENT_SIT_GROUND_CONSTRAINED);
#undef SIT_OVERRIDE
BASIC_OVERRIDE(HOVER, "Hover", false);
BASIC_OVERRIDE(HOVER_DOWN, "FlyDown", false);
BASIC_OVERRIDE(HOVER_UP, "FlyUp", false);
BASIC_OVERRIDE(CROUCH, "Crouch");
BASIC_OVERRIDE(CROUCHWALK, "CrouchWalk");
BASIC_OVERRIDE(FALLDOWN, "Fall");
BASIC_OVERRIDE(STANDUP, "StandUp");
BASIC_OVERRIDE(LAND, "Land");
BASIC_OVERRIDE(FLY, "Fly", false);
BASIC_OVERRIDE(FLYSLOW, "FlySlow", false);
ANY_OVERRIDE(override_low_priority, TYPE, "Typing");
mAOOverrides[STATE_AGENT_SWIM_DOWN] = new override_single(ANIM_AGENT_HOVER_DOWN, "SwimDown", true);
mAOOverrides[STATE_AGENT_SWIM_UP] = new override_single(ANIM_AGENT_HOVER_UP, "SwimUp", true);
mAOOverrides[STATE_AGENT_SWIM] = new override_single(ANIM_AGENT_FLY, "Swim", true);
mAOOverrides[STATE_AGENT_FLOAT] = new override_single(ANIM_AGENT_HOVER, "Float", true);
#undef BASIC_OVERRIDE
#undef ANY_OVERRIDE
auto swim_forced = gSavedSettings.getControl("AOSwimForced");
sSwimming = swim_forced->get().asBoolean() || is_underwater();
mConnections[0] = gSavedSettings.getControl("AOSitsEnabled")->getSignal()->connect([this](LLControlVariable*, const LLSD& val) {
if (!isAgentAvatarValid() || !gAgentAvatarp->isSitting()) return;
gAgent.sendAnimationRequest(mAOOverrides[gAgentAvatarp->getParent() ? STATE_AGENT_SIT : STATE_AGENT_SIT_GROUND]->ao_id, val.asBoolean() ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
});
const auto& swim_cb = [=](LLControlVariable*, const LLSD&){ toggleSwim(swim_forced->get().asBoolean() || is_underwater()); };
auto swim_enabled = gSavedSettings.getControl("AOSwimEnabled");
mConnections[1] = swim_enabled->getSignal()->connect(swim_cb);
mConnections[2] = swim_forced->getSignal()->connect([swim_cb, swim_enabled](LLControlVariable*, const LLSD& val) {
if (val.asBoolean()) // Automatically enable Swim AO.
swim_enabled->set(true);
swim_cb(nullptr, LLSD());
});
}
AOSystem::~AOSystem()
{
stopAllOverrides();
for (auto& ao : mAOOverrides)
{
if (ao)
{
delete ao;
ao = nullptr;
}
}
}
void AOSystem::requestConfigNotecard(bool reload)
{
LLUUID configncitem = (LLUUID)gSavedPerAccountSettings.getString("AOConfigNotecardID");
if (configncitem.notNull())
{
bool success = false;
if (const LLInventoryItem* item = gInventory.getItem(configncitem))
{
if (gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE) || gAgent.isGodlike())
{
if (item->getAssetUUID().notNull())
{
invfolderid = item->getParentUUID();
gAssetStorage->getInvItemAsset(LLHost::invalid,
gAgentID,
gAgentSessionID,
item->getPermissions().getOwner(),
LLUUID::null,
item->getUUID(),
item->getAssetUUID(),
item->getType(),
[reload](LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
{
parseNotecard(vfs, asset_uuid, type, status, reload);
},
nullptr,
true);
success = true;
}
}
}
if (!success) cmdline_printchat("Could not read the specified Config Notecard");
}
}
void AOSystem::initSingleton()
{
mAOStands.clear();
requestConfigNotecard();
}
void AOSystem::typing(bool start)
{
uuid_vec_t anims;
// If we're stopping, stop regardless, just in case the setting was toggled during (e.g.: keyboard shortcut)
if (!start || gSavedSettings.getBOOL("PlayTypingAnim")) // Linden typing
anims.push_back(ANIM_AGENT_TYPE);
if (const auto& ao = getIfExists()) // Typing override
anims.push_back(ao->mAOOverrides[STATE_AGENT_TYPE]->getOverride());
if (anims.empty()) return;
gAgent.sendAnimationRequests(anims, start ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
}
AOState GetStateFromToken(const std::string& strtoken)
{
if (strtoken == "[ Sitting On Ground ]") return STATE_AGENT_SIT_GROUND;
if (strtoken == "[ Sitting ]") return STATE_AGENT_SIT;
if (strtoken == "[ Crouching ]") return STATE_AGENT_CROUCH;
if (strtoken == "[ Crouch Walking ]") return STATE_AGENT_CROUCHWALK;
if (strtoken == "[ Standing Up ]") return STATE_AGENT_STANDUP;
if (strtoken == "[ Falling ]") return STATE_AGENT_FALLDOWN;
if (strtoken == "[ Flying Down ]") return STATE_AGENT_HOVER_DOWN;
if (strtoken == "[ Flying Up ]") return STATE_AGENT_HOVER_UP;
if (strtoken == "[ Flying Slow ]") return STATE_AGENT_FLYSLOW;
if (strtoken == "[ Flying ]") return STATE_AGENT_FLY;
if (strtoken == "[ Hovering ]") return STATE_AGENT_HOVER;
if (strtoken == "[ Jumping ]") return STATE_AGENT_JUMP;
if (strtoken == "[ Pre Jumping ]") return STATE_AGENT_PRE_JUMP;
if (strtoken == "[ Running ]") return STATE_AGENT_RUN;
if (strtoken == "[ Turning Right ]") return STATE_AGENT_TURNRIGHT;
if (strtoken == "[ Turning Left ]") return STATE_AGENT_TURNLEFT;
if (strtoken == "[ Walking ]") return STATE_AGENT_WALK;
if (strtoken == "[ Landing ]") return STATE_AGENT_LAND;
if (strtoken == "[ Standing ]") return STATE_AGENT_IDLE;
if (strtoken == "[ Swimming Down ]") return STATE_AGENT_SWIM_DOWN;
if (strtoken == "[ Swimming Up ]") return STATE_AGENT_SWIM_UP;
if (strtoken == "[ Swimming Forward ]") return STATE_AGENT_SWIM;
if (strtoken == "[ Floating ]") return STATE_AGENT_FLOAT;
if (strtoken == "[ Typing ]") return STATE_AGENT_TYPE;
return STATE_AGENT_END;
}
void AOSystem::updateStand()
{
auto& stand_ao = stand();
bool is_standing = stand_ao.playing;
if (is_standing) stand_ao.play(false); // Stop stand first
stand_ao.update(mAOStands, stand_iterator); // Now update stand
if (is_standing && !mAOStands.empty()) // Play stand if needed
stand_ao.play();
}
int AOSystem::cycleStand(bool next, bool random)
{
if (mAOStands.empty()) return -1;
const int size = mAOStands.size();
if (size > 1)
{
if (random && gSavedSettings.getBOOL("AOStandRandomize"))
for (auto previous = stand_iterator; previous == stand_iterator;
stand_iterator = ll_rand(size));
else
{
stand_iterator += next ? 1 : -1;
// Wrap around
if (stand_iterator == size) stand_iterator = 0;
else if (stand_iterator == -1) stand_iterator = size - 1;
}
if (auto floater = LLFloaterAO::findInstance())
if (auto combo = floater->getComboFromState(STATE_AGENT_IDLE))
combo->selectNthItem(stand_iterator);
// LL_INFOS() << "changing stand to " << mAOStands[stand_iterator].anim_name << LL_ENDL;
}
updateStand();
return stand_iterator;
}
void AOSystem::toggleSwim(bool underwater)
{
sSwimming = underwater && enable_swim();
if (isStanding()) return; // Don't bother if we're just standing (Who pushed us?!)
typedef std::array<overrides*, 4> flies_t;
// Stop all of the previous states
#define AOO(state) mAOOverrides[STATE_AGENT_##state]
const flies_t swims = { AOO(FLOAT), AOO(SWIM), AOO(SWIM_UP), AOO(SWIM_DOWN) };
const flies_t flies = { AOO(HOVER), AOO(FLY), AOO(HOVER_UP), AOO(HOVER_DOWN) };
#undef AOO
const auto& oldaos = sSwimming ? flies : swims;
const auto& newaos = sSwimming ? swims : flies;
for (auto i = 0; i < oldaos.size(); ++i)
{
auto& old = *oldaos[i];
if (old.playing)
{
old.play(false);
newaos[i]->play();
}
}
}
void AOSystem::doMotion(const LLUUID& id, bool start)
{
if (id.isNull() || !gAgentAvatarp) return;
overrides* aop = nullptr;
AOState state = STATE_AGENT_IDLE;
for (U8 i = STATE_AGENT_IDLE; !aop && i < STATE_AGENT_END; ++i)
{
auto& ao = mAOOverrides[i];
if (ao && ao->overrideAnim(sSwimming, id))
{
aop = ao;
state = (AOState)i;
}
}
if (aop)
{
// LL_INFOS() << "st" << (start ? "art" : "op") << " anim " << id << " state " << state << LL_ENDL;
aop->play(start);
}
}
void AOSystem::stopAllOverrides() const
{
if (!isAgentAvatarValid()) return;
uuid_vec_t anims;
for (auto& ao : mAOOverrides)
{
if (ao->playing)
{
anims.push_back(ao->getOverride());
ao->playing = false;
}
}
for (const auto& stand : mAOStands)
anims.push_back(stand.ao_id);
gAgent.sendAnimationRequests(anims, ANIM_REQUEST_STOP);
}
void AOSystem::parseNotecard(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, S32 status, bool reload)
{
if (status == LL_ERR_NOERR)
{
if (type == LLAssetType::AT_NOTECARD)
{
AOSystem* self = getIfExists();
S32 size = vfs->getSize(asset_uuid, LLAssetType::AT_NOTECARD);
U8* buffer = new U8[size];
vfs->getData(asset_uuid, type, buffer, 0, size);
LLMemoryStream str(buffer, size);
LLNotecard nc;
if (nc.importStream(str))
{
LL_INFOS() << "ao nc decode success" << LL_ENDL;
if (self && reload) self->stopAllOverrides();
auto floater = LLFloaterAO::findInstance();
if (floater)
for (auto& combo : floater->mCombos)
{
if (combo)
{
combo->clear();
combo->removeall();
}
}
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep("\n");
tokenizer tokline(nc.getText(), sep);
for (const auto& strline : tokline)
{
// LL_INFOS() << "uncommented line: " << strline << LL_ENDL;
boost::regex type("^(\\s*)(\\[ )(.*)( \\])");
boost::smatch what;
if (boost::regex_search(strline, what, type))
{
const std::string strtoken(what[0]);
const AOState state = GetStateFromToken(strtoken);
if (state == STATE_AGENT_END)
{
LL_WARNS() << "Invalid token: " << strtoken << LL_ENDL;
continue;
}
// LL_INFOS() << "type: " << strtoken << LL_ENDL;
LLComboBox* combo = floater ? floater->getComboFromState(state) : nullptr;
auto aop = (reload && self) ? self->mAOOverrides[state] : nullptr;
// LL_INFOS() << "anims in type: " << boost::regex_replace(strline, type, "") << LL_ENDL;
boost::char_separator<char> sep("|,");
std::string stranimnames(boost::regex_replace(strline, type, ""));
tokenizer tokanimnames(stranimnames, sep);
for (const auto& stranim : tokanimnames)
{
if (stranim.empty()) continue;
const auto& animid(getAssetIDByName(stranim));
// LL_INFOS() << invfolderid.asString().c_str() << LL_ENDL;
// LL_INFOS() << "anim: " << stranim.c_str() << " assetid: " << animid << LL_ENDL;
if (animid.notNull())
{
if (aop) // If we're reloading
{
if (state == STATE_AGENT_IDLE)
self->mAOStands.push_back({ animid, stranim });
else
aop->ao_id = animid;
}
if (combo && !combo->selectByValue(stranim)) // check if exists
combo->add(stranim, ADD_BOTTOM, true);
}
else cmdline_printchat("Warning: animation '" + stranim + "' could not be found (Section: " + strtoken + ").");
}
}
}
LL_INFOS() << "ao nc read sucess" << LL_ENDL;
if (self)
{
if (auto combo = floater ? floater->getComboFromState(STATE_AGENT_IDLE) : nullptr)
combo->selectNthItem(self->stand_iterator);
for (U8 i = STATE_AGENT_IDLE+1; i < STATE_AGENT_END; ++i)
{
auto& aop = self->mAOOverrides[i];
if (!aop) continue;
auto& ao = *aop;
const auto& setting = ao.setting;
if (!setting && ao.ao_id.isNull()) continue;
const auto& defaultanim = setting ? setting->get().asStringRef() : ao.ao_id.asString();
if (defaultanim.empty()) continue;
const LLUUID& ao_id = getAssetIDByName(defaultanim);
if (reload && ao_id.notNull()) ao.ao_id = ao_id;
if (LLComboBox* combo = floater ? floater->getComboFromState(i) : nullptr)
if (!combo->selectByValue(defaultanim))
combo->add(defaultanim, ADD_BOTTOM, true);
}
if (reload && isAgentAvatarValid())
{
// Fix the stand iter, container size may have changed
auto& iter = self->stand_iterator;
const auto& stands = self->mAOStands;
iter = llmin(iter, (int)stands.size()-1);
// Update the current stand
self->stand().update(stands, iter);
self->mAOStandTimer.reset();
const auto& anims = gAgentAvatarp->mPlayingAnimations;
bool playing = false;
for (auto& aop : self->mAOOverrides)
{
for (const auto& anim : anims)
{
if (aop && aop->overrideAnim(sSwimming, anim.first))
{
if (!aop->isLowPriority()) playing = true;
aop->play();
break;
}
}
}
if (!playing) self->stand().play(); // Play stand if nothing was being played, this sometimes happens
// Toggle typing AO the moment we toggle AO
typing(gAgent.getRenderState() & AGENT_STATE_TYPING);
}
}
}
else LL_INFOS() << "ao nc decode error" << LL_ENDL;
delete[] buffer;
}
}
else LL_INFOS() << "ao nc read error" << LL_ENDL;
}

101
indra/newview/aosystem.h Normal file
View File

@@ -0,0 +1,101 @@
#pragma once
#include "aostate.h"
#include "llcontrol.h"
#include "lleventtimer.h"
class AOSystem final : public LLSingleton<AOSystem>
{
friend class LLSingleton<AOSystem>;
friend class AOInvTimer;
friend class LLFloaterAO;
AOSystem();
~AOSystem();
public:
static void start(); // Runs the necessary actions to get the AOSystem ready, then initializes it.
void initSingleton() override;
static void typing(bool start);
int stand_iterator;
bool isStanding() const { return stand().playing; }
void updateStand();
int cycleStand(bool next = true, bool random = true);
void toggleSwim(bool underwater);
void doMotion(const LLUUID& id, bool start);
void startMotion(const LLUUID& id) { doMotion(id, true); }
void stopMotion(const LLUUID& id) { doMotion(id, false); }
void stopCurrentStand() const { stand().play(false); }
void stopAllOverrides() const;
protected:
struct struct_stands
{
LLUUID ao_id;
std::string anim_name;
};
typedef std::vector<struct_stands> stands_vec;
stands_vec mAOStands;
struct overrides
{
virtual bool overrideAnim(bool swimming, const LLUUID& anim) const = 0;
virtual const LLUUID& getOverride() const { return ao_id; }
virtual bool play_condition() const; // True if prevented from playing
virtual bool isLowPriority() const { return false; }
void play(bool start = true);
LLUUID ao_id;
LLPointer<LLControlVariable> setting;
bool playing;
virtual ~overrides() {}
protected:
overrides(const char* setting_name);
};
friend struct override_low_priority;
friend struct override_single;
friend struct override_sit;
struct override_stand final : public overrides
{
override_stand() : overrides(nullptr) {}
bool overrideAnim(bool swimming, const LLUUID& anim) const override;
bool play_condition() const override;
bool isLowPriority() const override { return true; }
void update(const stands_vec& stands, const int& iter)
{
if (stands.empty()) ao_id.setNull();
else ao_id = stands[iter].ao_id;
}
};
std::array<overrides*, STATE_AGENT_END> mAOOverrides;
override_stand& stand() const { return static_cast<override_stand&>(*mAOOverrides[STATE_AGENT_IDLE]); }
private:
std::array<boost::signals2::scoped_connection, 3> mConnections;
class AOStandTimer final : public LLEventTimer
{
friend class AOSystem;
public:
AOStandTimer() : LLEventTimer(F32_MAX) {}
~AOStandTimer()
{
// LL_INFOS() << "dead" << LL_ENDL;
}
BOOL tick() override
{
// LL_INFOS() << "tick" << LL_ENDL;
if (auto ao = AOSystem::getIfExists())
ao->cycleStand();
return false;
}
void reset();
};
AOStandTimer mAOStandTimer;
static void requestConfigNotecard(bool reload = true);
static void parseNotecard(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType::EType type, S32 status, bool reload);
};

View File

@@ -2,7 +2,7 @@
<array>
<map>
<key>default_grids_version</key><string>22</string>
<key>default_grids_version</key><string>23</string>
</map>
<!-- Second Life -->
@@ -11,7 +11,7 @@
<key>gridname</key><string>Second Life</string>
<key>platform</key><string>SecondLife</string>
<key>loginuri</key><string>https://login.agni.lindenlab.com/cgi-bin/login.cgi</string>
<key>loginpage</key><string>http://viewer-login.agni.lindenlab.com/</string>
<key>loginpage</key><string>https://viewer-splash.secondlife.com/</string>
<key>helperuri</key><string>https://secondlife.com/helpers/</string>
<key>website</key><string>http://secondlife.com/</string>
<key>support</key><string>http://secondlife.com/support/</string>
@@ -26,7 +26,7 @@
<key>gridnick</key><string>secondlife_beta</string>
<key>gridname</key><string>Second Life BETA</string>
<key>helperuri</key><string>http://aditi-secondlife.webdev.lindenlab.com/helpers/</string>
<key>loginpage</key><string>http://viewer-login.agni.lindenlab.com/</string>
<key>loginpage</key><string>https://viewer-splash.secondlife.com/</string>
<key>loginuri</key><string>https://login.aditi.lindenlab.com/cgi-bin/login.cgi</string>
<key>password</key><string>http://secondlife.com/account/request.php</string>
<key>platform</key><string>SecondLife</string>

View File

@@ -1052,5 +1052,28 @@
<map/>
<key>llGetMaxScaleFactor</key>
<map/>
<!-- Experience Tools new functions -->
<key>llAgentInExperience</key>
<map/>
<key>llGetExperienceDetails</key>
<map/>
<key>llRequestExperiencePermissions</key>
<map/>
<key>llReadKeyValue</key>
<map/>
<key>llCreateKeyValue</key>
<map/>
<key>llUpdateKeyValue</key>
<map/>
<key>llDeleteKeyValue</key>
<map/>
<key>llDataSizeKeyValue</key>
<map/>
<key>llKeysKeyValue</key>
<map/>
<key>llKeyCountKeyValue</key>
<map/>
<key>llGetExperienceErrorMessage</key>
<map/>
</map>
</llsd>

View File

@@ -133,6 +133,17 @@
media_plugin_libvlc
</impl>
</scheme>
<scheme name="example">
<label name="example_label">
Example Plugin scheme trigger
</label>
<widgettype>
movie
</widgettype>
<impl>
media_plugin_example
</impl>
</scheme>
<scheme name="libvlc">
<label name="libvlc_label">
LibVLC supported media
@@ -474,8 +485,8 @@
media_plugin_libvlc
</impl>
</mimetype>
<mimetype menu="1" name="video/libvlc">
<label name="video/libvlc_label">
<mimetype menu="1" name="video/quicktime">
<label name="video/quicktime_label">
Movie (QuickTime)
</label>
<widgettype>
@@ -515,7 +526,7 @@
movie
</widgettype>
<impl>
media_plugin_cef
media_plugin_libvlc
</impl>
</mimetype>
</mimetypes>

View File

@@ -497,6 +497,19 @@
<key>IsCOA</key>
<integer>1</integer>
</map>
<key>AOSwimForced</key>
<map>
<key>Comment</key>
<string>Sets AOSwimEnabled to true, and plays swims instead of flies, even if not underwater.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<key>IsCOA</key>
<integer>1</integer>
</map>
<key>AONoStandsInMouselook</key>
<map>
<key>Comment</key>
@@ -2556,6 +2569,17 @@ This should be as low as possible, but too low may break functionality</string>
<integer>1</integer>
</map>
<!-- Standard SL options (To my knowledge) -->
<key>CrashHostUrl</key>
<map>
<key>Comment</key>
<string>A URL pointing to a crash report handler; overrides cluster negotiation to locate crash handler.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string />
</map>
<key>AFKTimeout</key>
<map>
<key>Comment</key>
@@ -7500,6 +7524,54 @@ This should be as low as possible, but too low may break functionality</string>
<integer>0</integer>
</array>
</map>
<key>FloaterExperiencePickerRect</key>
<map>
<key>Comment</key>
<string>Rectangle for experience picker floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Rect</string>
<key>Value</key>
<array>
<integer>300</integer>
<integer>600</integer>
<integer>800</integer>
<integer>700</integer>
</array>
</map>
<key>FloaterExperienceProfileRect</key>
<map>
<key>Comment</key>
<string>Rectangle for experience profile floaters</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Rect</string>
<key>Value</key>
<array>
<integer>377</integer>
<integer>650</integer>
<integer>345</integer>
<integer>128</integer>
</array>
</map>
<key>FloaterExperiencesRect</key>
<map>
<key>Comment</key>
<string>Rectangle for experiences floater</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Rect</string>
<key>Value</key>
<array>
<integer>300</integer>
<integer>600</integer>
<integer>700</integer>
<integer>700</integer>
</array>
</map>
<key>FloaterFindRect2</key>
<map>
<key>Comment</key>
@@ -8257,7 +8329,7 @@ This should be as low as possible, but too low may break functionality</string>
<array>
<integer>0</integer>
<integer>512</integer>
<integer>480</integer>
<integer>500</integer>
<integer>0</integer>
</array>
</map>
@@ -11677,17 +11749,6 @@ This should be as low as possible, but too low may break functionality</string>
<key>Value</key>
<integer>344</integer>
</map>
<key>RevokePermsOnStandUp</key>
<map>
<key>Comment</key>
<string>When enabled, revokes any permission granted to an object you don't own and from which your avatar is standing up</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>PickerContextOpacity</key>
<map>
<key>Comment</key>
@@ -12567,6 +12628,18 @@ This should be as low as possible, but too low may break functionality</string>
<integer>128</integer>
</map>
<key>OctreeMinimumNodeSize</key>
<map>
<key>Comment</key>
<string>Minimum size of any octree node</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.01</real>
</map>
<key>OctreeReserveNodeCapacity</key>
<map>
<key>Comment</key>
@@ -14579,6 +14652,17 @@ This should be as low as possible, but too low may break functionality</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RevokePermsOnStandUp</key>
<map>
<key>Comment</key>
<string>When enabled, revokes any permission granted to an object you don't own and from which your avatar is standing up</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RevokePermsOnStopAnimation</key>
<map>
<key>Comment</key>

View File

@@ -565,6 +565,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>AlchemyDisableSimCamConstraint</key>
<map>
<key>Comment</key>
<string>Disable the push the simulator applies when camera collides with objects</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>AscentFlyAlwaysEnabled</key>
<map>
<key>Comment</key>
@@ -973,6 +984,17 @@ RIP Latif Khalifa.</string>
<key>Value</key>
<boolean>1</boolean>
</map>
<key>SinguOwnerSayAsErrors</key>
<map>
<key>Comment</key>
<string>llOwnerSay will show up in the script error console instead of in chat.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<boolean>0</boolean>
</map>
<key>SinguPostProcessDefault</key>
<map>
<key>Comment</key>
@@ -1164,6 +1186,17 @@ Changing this setting only affects new text.</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>LiruUseMarkedColor</key>
<map>
<key>Comment</key>
<string>Whether or not to use the color of marks done on radar and minimap to color tags and chat from those individuals</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>OBJExportNotifyFailed</key>
<map>
<key>Comment</key>
@@ -1622,6 +1655,19 @@ Changing this setting only affects new text.</string>
<key>IsCOA</key>
<integer>1</integer>
</map>
<key>ToolbarVisibleExperiences</key>
<map>
<key>Comment</key>
<string>Whether or not the button for the experiences floater is on the toolbar</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<boolean>0</boolean>
<key>IsCOA</key>
<integer>1</integer>
</map>
<key>ToolbarVisibleFastTimers</key>
<map>
<key>Comment</key>

View File

@@ -70,7 +70,10 @@ LLPrefsAscentChat::LLPrefsAscentChat()
}
childSetEnabled("reset_antispam", started);
getChild<LLUICtrl>("reset_antispam")->setCommitCallback(boost::bind(NACLAntiSpamRegistry::purgeAllQueues));
getChild<LLUICtrl>("reset_antispam")->setCommitCallback([](LLUICtrl* ctrl, const LLSD& param) {
if (auto inst = NACLAntiSpamRegistry::getIfExists())
inst->resetQueues();
});
getChild<LLUICtrl>("autoreplace")->setCommitCallback(boost::bind(LLFloaterAutoReplaceSettings::showInstance, LLSD()));
getChild<LLUICtrl>("KeywordsOn")->setCommitCallback(boost::bind(&LLPrefsAscentChat::onCommitKeywords, this, _1));

View File

@@ -207,6 +207,7 @@ void LLPrefsAscentSys::refreshValues()
mDisplayScriptJumps = gSavedSettings.getBOOL("AscentDisplayTotalScriptJumps");
mNumScriptDiff = gSavedSettings.getF32("Ascentnumscriptdiff");
mReplaceLinks = gSavedSettings.getBOOL("SinguReplaceLinks");
mEmergencySeconds = gSavedPerAccountSettings.getU32("EmergencyTeleportSeconds");
mLandmark = gSavedPerAccountSettings.getString("EmergencyTeleportLandmark");
mLandmarkBackup = gSavedPerAccountSettings.getString("EmergencyTeleportLandmarkBackup");
@@ -353,6 +354,7 @@ void LLPrefsAscentSys::cancel()
gSavedSettings.setBOOL("AscentDisplayTotalScriptJumps", mDisplayScriptJumps);
gSavedSettings.setF32("Ascentnumscriptdiff", mNumScriptDiff);
gSavedSettings.setBOOL("SinguReplaceLinks", mReplaceLinks);
gSavedPerAccountSettings.setU32("EmergencyTeleportSeconds", mEmergencySeconds);
gSavedPerAccountSettings.setString("EmergencyTeleportLandmark", mLandmark);
gSavedPerAccountSettings.setString("EmergencyTeleportLandmarkBackup", mLandmarkBackup);

Some files were not shown because too many files have changed in this diff Show More