diff --git a/.gitattributes b/.gitattributes index 30cc9de8f17..5c7f5b73b07 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,5 @@ * text eol=lf -# VSTool (normalization disabled) -indra/tools/vstool/* -text - # Images *.bmp binary *.BMP binary diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4bf2af644ae..5a5628ede2b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,6 +1,7 @@ name: Build on: + workflow_dispatch: pull_request: push: branches: ["main", "release/*", "project/*"] @@ -42,7 +43,7 @@ jobs: needs: setup strategy: matrix: - runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge"]' || '["windows-latest","macos-15"]') }} + runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge"]' || '["windows-2022","macos-15-xlarge"]') }} configuration: ${{ fromJson(needs.setup.outputs.configurations) }} runs-on: ${{ matrix.runner }} outputs: @@ -64,7 +65,7 @@ jobs: # autobuild-package.xml. AUTOBUILD_VCS_INFO: "true" AUTOBUILD_VSVER: "170" - DEVELOPER_DIR: "/Applications/Xcode_16.1.app/Contents/Developer" + DEVELOPER_DIR: "/Applications/Xcode_16.4.app/Contents/Developer" # Ensure that Linden viewer builds engage Bugsplat. BUGSPLAT_DB: ${{ needs.setup.outputs.bugsplat_db }} build_coverity: false @@ -93,7 +94,6 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.11" - - name: Checkout build variables uses: actions/checkout@v4 with: @@ -306,11 +306,11 @@ jobs: AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} needs: build - runs-on: windows-latest + runs-on: windows-2022 steps: - name: Sign and package Windows viewer if: env.AZURE_KEY_VAULT_URI && env.AZURE_CERT_NAME && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET && env.AZURE_TENANT_ID - uses: secondlife/viewer-build-util/sign-pkg-windows@v2 + uses: secondlife/viewer-build-util/sign-pkg-windows@v2.0.4 with: vault_uri: "${{ env.AZURE_KEY_VAULT_URI }}" cert_name: "${{ env.AZURE_CERT_NAME }}" diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml index 7866f943b5a..627ba512c41 100644 --- a/.github/workflows/cla.yaml +++ b/.github/workflows/cla.yaml @@ -23,4 +23,4 @@ jobs: path-to-signatures: signatures.json remote-organization-name: secondlife remote-repository-name: cla-signatures - allowlist: callum@mbp.localdomain,rye@lindenlab.com + allowlist: callum@mbp.localdomain,rye@lindenlab.com,rye diff --git a/.github/workflows/qatest.yaml b/.github/workflows/qatest.yaml index 4e10900441b..b6883d88d43 100644 --- a/.github/workflows/qatest.yaml +++ b/.github/workflows/qatest.yaml @@ -43,13 +43,25 @@ jobs: artifact: Windows-installer install-path: 'C:\viewer-automation-main' - os: windows - runner: qa-dan-asus + runner: qa-windows-asus-dan + artifact: Windows-installer + install-path: 'C:\viewer-automation-main' + - os: windows + runner: qa-windows-kurt artifact: Windows-installer install-path: 'C:\viewer-automation-main' + - os: mac + runner: qa-mac-dan + artifact: macOS-installer + install-path: '$HOME/Documents/viewer-automation' - os: mac runner: qa-mac-atlas artifact: macOS-installer install-path: '$HOME/Documents/viewer-automation' + - os: mac + runner: qa-mac-caleb + artifact: macOS-installer + install-path: '$HOME/Documents/viewer-automation' fail-fast: false runs-on: [self-hosted, "${{ matrix.runner }}"] diff --git a/.gitignore b/.gitignore index 3b3666af843..c4accf37b5b 100755 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,6 @@ debian/files debian/secondlife-appearance-utility* debian/secondlife-viewer* indra/.distcc -indra/cmake/* indra/out/* indra/packages/* diff --git a/autobuild.xml b/autobuild.xml index f792bac7895..43bdf6ed377 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -46,11 +46,11 @@ archive hash - 579a46d77802e301856c93792d39d43bbf939987 + a21487f4e3a68721fd97edef117795a1b7212a77 hash_algorithm sha1 url - https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.4-r2/apr_suite-1.7.4-10338381102-darwin64-10338381102.tar.zst + https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r1/apr_suite-1.7.5-12259255574-darwin64-12259255574.tar.zst name darwin64 @@ -60,11 +60,11 @@ archive hash - 2e5cf11f8774023408402df860d3d1f4a6668500 + 45baf82d3366734e542a2a3749f495b64f5513b4 hash_algorithm sha1 url - https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.4-r2/apr_suite-1.7.4-10338381102-linux64-10338381102.tar.zst + https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r1/apr_suite-1.7.5-12259255574-linux64-12259255574.tar.zst name linux64 @@ -74,11 +74,11 @@ archive hash - 7eb6b8f294c4563a07fec3578be2d04af17a60cb + bdd35d3b9580d3cdcb98afae639936aaa40e24c4 hash_algorithm sha1 url - https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.4-r2/apr_suite-1.7.4-10338381102-windows64-10338381102.tar.zst + https://github.com/secondlife/3p-apr_suite/releases/download/v1.7.5-r1/apr_suite-1.7.5-12259255574-windows64-12259255574.tar.zst name windows64 @@ -91,7 +91,7 @@ copyright Copyright © 2012 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. version - 1.7.4-10338381102 + 1.7.5-12259255574 name apr_suite description @@ -99,16 +99,6 @@ boost - copyright - (see individual source files) - description - Boost C++ Libraries - license - boost 1.0 - license_file - LICENSES/boost.txt - name - boost platforms darwin64 @@ -116,11 +106,11 @@ archive hash - 6bf5f4afddf87d48c069d781b5ef2d44d6ddf2d5 + a4553df5b8fde2e9cd54ebb94c6efb8eb5fe3c38 hash_algorithm sha1 url - https://github.com/secondlife/3p-boost/releases/download/v1.86.0-e2bee1e/boost-1.86-darwin64-10475904468.tar.zst + https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-darwin64-13246092114.tar.zst name darwin64 @@ -130,11 +120,11 @@ archive hash - 3c0ba2a87e78d76c81da95fa87579bf4964242e1 + 4a2a19dc5cb555e157ad894ba917f5a83a35b20d hash_algorithm sha1 url - https://github.com/secondlife/3p-boost/releases/download/v1.86.0-e2bee1e/boost-1.86-linux64-10475904468.tar.zst + https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-linux64-13246092114.tar.zst name linux64 @@ -144,18 +134,28 @@ archive hash - d1dd5d629b254d1b361c5a0fa210b5f3283e8a20 + 8a1fa9366bfe49009286e4805d7aaedb7c3df82e hash_algorithm sha1 url - https://github.com/secondlife/3p-boost/releases/download/v1.86.0-e2bee1e/boost-1.86-windows64-10475904468.tar.zst + https://github.com/secondlife/3p-boost/releases/download/v1.86.0-be1a669/boost-1.86-windows64-13246092114.tar.zst name windows64 + license + boost 1.0 + license_file + LICENSES/boost.txt + copyright + (see individual source files) version 1.86 + name + boost + description + Boost C++ Libraries bugsplat @@ -205,14 +205,6 @@ colladadom - copyright - Copyright 2006 Sony Computer Entertainment Inc. - license - SCEA - license_file - LICENSES/collada.txt - name - colladadom platforms darwin64 @@ -220,11 +212,11 @@ archive hash - 18b46ce8ebb5ae6ef6527b4e95408433e29ad3f4 + bf2fe4e8272e990bc8687b3b37bf4bb2b2ad6eb4 hash_algorithm sha1 url - https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r8/colladadom-2.3.0-r8-darwin64-10476582237.tar.zst + https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r10/colladadom-2.3.0-r10-darwin64-13259816660.tar.zst name darwin64 @@ -234,11 +226,11 @@ archive hash - c088fe0be9ce7e42983c3c7708abe4ac8bd5a894 + 118e509ca464182ef4b94ee8c4aa5b14a6c52a94 hash_algorithm sha1 url - https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r8/colladadom-2.3.0-r8-linux64-10476582237.tar.zst + https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r10/colladadom-2.3.0-r10-linux64-13259816660.tar.zst name linux64 @@ -248,18 +240,26 @@ archive hash - 8bfa9f1a78d077f3bd422f14ae360150b98c82f9 + d7aee1b2ec17bd88a2c27359281b58a11ec52d48 hash_algorithm sha1 url - https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r8/colladadom-2.3.0-r8-windows64-10476582237.tar.zst + https://github.com/secondlife/3p-colladadom/releases/download/v2.3-r10/colladadom-2.3.0-r10-windows64-13259816660.tar.zst name windows64 + license + SCEA + license_file + LICENSES/collada.txt + copyright + Copyright 2006 Sony Computer Entertainment Inc. version - 2.3.0-r8 + 2.3.0-r10 + name + colladadom cubemaptoequirectangular @@ -290,6 +290,8 @@ url https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-linux64-d7afe27.tar.zst + name + linux64 windows64 @@ -326,11 +328,11 @@ archive hash - 9c74adfd217fcc04869ef574078bc56a4a1380f3 + e742b1e2d0a58d607b023bf55411041ac65e8a76 hash_algorithm sha1 url - https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r1/curl-7.54.1-10342910827-darwin64-10342910827.tar.zst + https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r3/curl-7.54.1-13259824618-darwin64-13259824618.tar.zst name darwin64 @@ -340,11 +342,11 @@ archive hash - 325ad581a1ba99fbc1e74d48481e07546eaf1e0e + 49621c70f385d37c95bcb69a9a24d86ac25f4781 hash_algorithm sha1 url - https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r1/curl-7.54.1-10342910827-linux64-10342910827.tar.zst + https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r3/curl-7.54.1-13259824618-linux64-13259824618.tar.zst name linux64 @@ -354,11 +356,11 @@ archive hash - 794480208e72a928552760cd048438b90aa1c80d + 2522201692116cf0adb7203e169be9126885108c hash_algorithm sha1 url - https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r1/curl-7.54.1-10342910827-windows64-10342910827.tar.zst + https://github.com/secondlife/3p-curl/releases/download/v7.54.1-r3/curl-7.54.1-13259824618-windows64-13259824618.tar.zst name windows64 @@ -371,7 +373,7 @@ copyright Copyright (c) 1996 - 2014, Daniel Stenberg, (daniel@haxx.se). version - 7.54.1-10342910827 + 7.54.1-13259824618 name curl description @@ -441,16 +443,6 @@ dullahan - copyright - Copyright (c) 2017, Linden Research, Inc. - description - A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies. - license - MPL - license_file - LICENSES/LICENSE.txt - name - dullahan platforms darwin64 @@ -458,11 +450,11 @@ archive hash - 7fde76e3f0e62d0e0593b6157f4d740ecef2429d + d44256458ff0ef4db4c91e8e8cc83e8f98b4f1b8 hash_algorithm sha1 url - https://github.com/secondlife/dullahan/releases/download/v1.14.0-r3/dullahan-1.14.0.202408091638_118.4.1_g3dd6078_chromium-118.0.5993.54-darwin64-10322607516.tar.zst + https://github.com/secondlife/dullahan/releases/download/v1.21.0-CEF_139.0.28/dullahan-1.21.0.202508272158_139.0.28_g55ab8a8_chromium-139.0.7258.139-darwin64-17279703032.tar.zst name darwin64 @@ -486,18 +478,28 @@ archive hash - 4124c79d8b0e319877ffa4c12581d5c1318b4d93 + 9d5af766a87052808e4062978504e9af124fb558 hash_algorithm sha1 url - https://github.com/secondlife/dullahan/releases/download/v1.14.0-r3/dullahan-1.14.0.202408091639_118.4.1_g3dd6078_chromium-118.0.5993.54-windows64-10322607516.tar.zst + https://github.com/secondlife/dullahan/releases/download/v1.21.0-CEF_139.0.28/dullahan-1.21.0.202508272159_139.0.28_g55ab8a8_chromium-139.0.7258.139-windows64-17279703032.tar.zst name windows64 + license + MPL + license_file + LICENSES/LICENSE.txt + copyright + Copyright (c) 2017, Linden Research, Inc. version - 1.14.0.202408091639_118.4.1_g3dd6078_chromium-118.0.5993.54 + 1.21.0.202508272158_139.0.28_g55ab8a8_chromium-139.0.7258.139 + name + dullahan + description + A headless browser SDK that uses the Chromium Embedded Framework (CEF). It is designed to make it easier to write applications that render modern web content directly to a memory buffer, inject synthesized mouse and keyboard events as well as interact with web based features like JavaScript or cookies. emoji_shortcodes @@ -542,11 +544,11 @@ archive hash - 8cc4f38fd809d9ff5d8ca617d7e068eb236f4162 + e0ba69946f2203c03faf89c1f6d5bbc48d88d2a9 hash_algorithm sha1 url - https://github.com/secondlife/3p-expat/releases/download/v2.6.2-r5/expat-2.6.2-r5-darwin64-10337781902.tar.zst + https://github.com/secondlife/3p-expat/releases/download/v2.6.4-r1/expat-2.6.4-r1-darwin64-11943227858.tar.zst name darwin64 @@ -556,11 +558,11 @@ archive hash - d7f3bbfd65fce365c3cd5be9ab72072580408dec + 13483477c1f8b4bad9055fba561c64137453c3da hash_algorithm sha1 url - https://github.com/secondlife/3p-expat/releases/download/v2.6.2-r5/expat-2.6.2-r5-linux64-10337781902.tar.zst + https://github.com/secondlife/3p-expat/releases/download/v2.6.4-r1/expat-2.6.4-r1-linux64-11943227858.tar.zst name linux64 @@ -570,11 +572,11 @@ archive hash - f11d91205bb753d7389a73e629627b200219c62f + 542af7d8bb8de3297c80c23a771bbcb513a630b7 hash_algorithm sha1 url - https://github.com/secondlife/3p-expat/releases/download/v2.6.2-r5/expat-2.6.2-r5-windows64-10337781902.tar.zst + https://github.com/secondlife/3p-expat/releases/download/v2.6.4-r1/expat-2.6.4-r1-windows64-11943227858.tar.zst name windows64 @@ -587,7 +589,7 @@ copyright Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper - Copyright (c) 2001-2022 Expat maintainers. version - 2.6.2-r5 + 2.6.4-r1 name expat description @@ -625,16 +627,6 @@ freetype - copyright - Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. - description - Font rendering library - license - FreeType - license_file - LICENSES/freetype.txt - name - freetype platforms darwin64 @@ -642,11 +634,11 @@ archive hash - 51ad743c8943602913eedd2b6e2309abf46849d8 + 5e6c7b9aaf73d90d7feab846a4024193c48eff6c hash_algorithm sha1 url - https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-cb2e120/freetype-2.13.3-cb2e120-darwin64-10475886095.tar.zst + https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r3/freetype-2.13.3-r3-darwin64-13259804885.tar.zst name darwin64 @@ -656,11 +648,11 @@ archive hash - bc27e272e004dc2fc573550e8c1cd8b4ad07f5b2 + a9a3c371958e64a49b07d7be8f59218dfd6b0352 hash_algorithm sha1 url - https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-cb2e120/freetype-2.13.3-cb2e120-linux64-10475886095.tar.zst + https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r3/freetype-2.13.3-r3-linux64-13259804885.tar.zst name linux64 @@ -670,18 +662,28 @@ archive hash - 01971b998122a17c97e3616c428cc77077a0c39a + ad7fbc4a01607ec43d86035a49dadd43d6f2a4e5 hash_algorithm sha1 url - https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-cb2e120/freetype-2.13.3-cb2e120-windows64-10475886095.tar.zst + https://github.com/secondlife/3p-freetype/releases/download/v2.13.3-r3/freetype-2.13.3-r3-windows64-13259804885.tar.zst name windows64 + license + FreeType + license_file + LICENSES/freetype.txt + copyright + Copyright 2006, 2007, 2008, 2009, 2010 by David Turner, Robert Wilhelm, and Werner Lemberg. version - 2.13.3-cb2e120 + 2.13.3-r3 + name + freetype + description + Font rendering library glext @@ -916,11 +918,11 @@ archive hash - f271809c0d4244128fb52a71226a4d7674e14e0a + b05374300cdd40c381614f2ee4497de340eda991 hash_algorithm sha1 url - https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-9165e47/jpegencoderbasic-1.0-darwin64-9165e47.tar.zst + https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-790015a/jpegencoderbasic-1.0-darwin64-790015a.tar.zst name darwin64 @@ -930,23 +932,25 @@ archive hash - 35d6a617444fde9c8a5e998ef29dc43b95747637 + 23daab838f4b8f92e5dc1a2f6c568cb7b0cb43b7 hash_algorithm sha1 url - https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-9165e47/jpegencoderbasic-1.0-linux64-9165e47.tar.zst + https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-790015a/jpegencoderbasic-1.0-linux64-790015a.tar.zst + name + linux64 windows64 archive hash - 8ec22e9fc8734ba3d1826f4b88171a6017cc8676 + 23e8ba22aadf88d249a21844bfcdd01138c05937 hash_algorithm sha1 url - https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-9165e47/jpegencoderbasic-1.0-windows64-9165e47.tar.zst + https://github.com/secondlife/3p-jpeg_encoder_js/releases/download/v1.0-790015a/jpegencoderbasic-1.0-windows64-790015a.tar.zst name windows64 @@ -972,11 +976,11 @@ archive hash - 34cf4fdbbc999e67b0528f7ca3c7f31f35267ecf + 10f14875ce5c7f5028217c8b7468733190fd333d hash_algorithm sha1 url - https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.3-r2/libjpeg_turbo-3.0.3-r2-windows64-10341191820.tar.zst + https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.4-r1/libjpeg_turbo-3.0.4-r1-windows64-11968659895.tar.zst name windows64 @@ -986,11 +990,11 @@ archive hash - 5ff05a0e5ed0aba1514b84d3c2edaf70c18738b5 + d3b1b0fde28c8cf0c33fed167dba87bba5c6cc64 hash_algorithm sha1 url - https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.3-r2/libjpeg_turbo-3.0.3-r2-linux64-10341191820.tar.zst + https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.4-r1/libjpeg_turbo-3.0.4-r1-linux64-11968659895.tar.zst name linux64 @@ -1000,11 +1004,11 @@ archive hash - 7c38eabc050b4a6bdb183a1d7a38da885341049c + 79e78cbaaec9a99c0ae4a5cdd4a98535c8fa3c6d hash_algorithm sha1 url - https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.3-r2/libjpeg_turbo-3.0.3-r2-darwin64-10341191820.tar.zst + https://github.com/secondlife/3p-libjpeg-turbo/releases/download/v3.0.4-r1/libjpeg_turbo-3.0.4-r1-darwin64-11968659895.tar.zst name darwin64 @@ -1017,7 +1021,7 @@ copyright Copyright (C)2009-2024 D. R. Commander. All Rights Reserved. Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. version - 3.0.3-r2 + 3.0.4-r1 name libjpeg-turbo canonical_repo @@ -1036,11 +1040,11 @@ creds github hash - ad72fa1d103df777906f0d98f3e882b9916aeada + da318f0813e4126d90e35b22a8dce235e908707a hash_algorithm sha1 url - https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774118 + https://api.github.com/repos/secondlife/3p-kdu/releases/assets/208381808 name darwin64 @@ -1052,11 +1056,11 @@ creds github hash - e46e4ac93a237b5c4a14183766f76ba5d58935a2 + 1ba58cf884726dfdf02a7662d52f1befe3f16d44 hash_algorithm sha1 url - https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774125 + https://api.github.com/repos/secondlife/3p-kdu/releases/assets/208381812 name linux64 @@ -1068,11 +1072,11 @@ creds github hash - bb37557f78c72b26580a521f8b8dabfa1b34e6e6 + e8d693089b9ecd15b6644f13ada7ae7c317944df hash_algorithm sha1 url - https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774126 + https://api.github.com/repos/secondlife/3p-kdu/releases/assets/208381814 name windows64 @@ -1084,11 +1088,11 @@ creds github hash - 711b82f9f588d3a125af7dcd8c81f93d9c343a7d + 85e294becce8b2ac5d2e5e052b0e21ff865d1108 hash_algorithm sha1 url - https://api.github.com/repos/secondlife/3p-kdu/releases/assets/136774121 + https://api.github.com/repos/secondlife/3p-kdu/releases/assets/208381806 name linux @@ -1101,7 +1105,7 @@ copyright Kakadu software version - 7.10.4.4b9ec5f + 8.4.1.11976899217 name kdu description @@ -1116,11 +1120,11 @@ archive hash - e71ae7a645603fe967a69aa5beb5b3009185e177 + 91acd05f450162b07ca2f68094778c483d28128d hash_algorithm sha1 url - https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r1/libhunspell-1.7.2.10207243663-darwin64-10207243663.tar.zst + https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r2/libhunspell-1.7.2.11968900321-darwin64-11968900321.tar.zst name darwin64 @@ -1130,11 +1134,11 @@ archive hash - 275ffb7f60064d8008aed8406f80f34229f651fc + 10e5b5d793c3c5cb5335dea89734302bda5a9f59 hash_algorithm sha1 url - https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r1/libhunspell-1.7.2.10207243663-linux64-10207243663.tar.zst + https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r2/libhunspell-1.7.2.11968900321-linux64-11968900321.tar.zst name linux64 @@ -1144,11 +1148,11 @@ archive hash - 89ff24e93eaeca7949ccdb5cc368f938f5b1f307 + 0f7b9c46dc4e81a6296e4836467f5fe52aa5761d hash_algorithm sha1 url - https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r1/libhunspell-1.7.2.10207243663-windows64-10207243663.tar.zst + https://github.com/secondlife/3p-libhunspell/releases/download/v1.7.2-r2/libhunspell-1.7.2.11968900321-windows64-11968900321.tar.zst name windows64 @@ -1161,7 +1165,7 @@ copyright LGPL 2.1 version - 1.7.2.10207243663 + 1.7.2.11968900321 name libhunspell description @@ -1176,11 +1180,11 @@ archive hash - e3dd320c90e67e0c80caf4d4df23257b0196dfb6 + d1638886671b31935ea7e3c824e015ea1a45b12e hash_algorithm sha1 url - https://github.com/secondlife/3p-libndofdev/releases/download/v0.1.8e9edc7/libndofdev-0.1.8e9edc7-darwin64-8e9edc7.tar.zst + https://github.com/secondlife/3p-libndofdev/releases/download/v0.1.a0b7d99/libndofdev-0.1.11968678219-darwin64-11968678219.tar.zst name darwin64 @@ -1190,11 +1194,11 @@ archive hash - ae9d554e8839f42230b8ed6c850445d54654a38f + 7b3e504885c4c0cc75db298e682f408c4f2e95f7 hash_algorithm sha1 url - https://github.com/secondlife/3p-libndofdev/releases/download/v0.1.8e9edc7/libndofdev-0.1.8e9edc7-windows64-8e9edc7.tar.zst + https://github.com/secondlife/3p-libndofdev/releases/download/v0.1.a0b7d99/libndofdev-0.1.11968678219-windows64-11968678219.tar.zst name windows64 @@ -1207,7 +1211,7 @@ copyright Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved. version - 0.1.8e9edc7 + 0.1.11968678219 name libndofdev description @@ -1222,11 +1226,11 @@ archive hash - 6fe46ed1e2e40616abdacf7115e510645d5f62e7 + a453355ee032f79aea4142218a957085a22c7656 hash_algorithm sha1 url - https://github.com/secondlife/3p-libpng/releases/download/v1.6.43-r2/libpng-1.6.43-r2-darwin64-10329429325.tar.zst + https://github.com/secondlife/3p-libpng/releases/download/v1.6.44-r2/libpng-1.6.44-r2-darwin64-13246065198.tar.zst name darwin64 @@ -1236,11 +1240,11 @@ archive hash - b54a4710d9c3ddfa044e1d29f9c38974e9fc645d + 75c7608646c9f5b99b1a9e3946326e2804a304d7 hash_algorithm sha1 url - https://github.com/secondlife/3p-libpng/releases/download/v1.6.43-r2/libpng-1.6.43-r2-linux64-10329429325.tar.zst + https://github.com/secondlife/3p-libpng/releases/download/v1.6.44-r2/libpng-1.6.44-r2-linux64-13246065198.tar.zst name linux64 @@ -1250,11 +1254,11 @@ archive hash - eddb96c73c8916bf71eaa5d0edb812d20e72c255 + 09af51774c4ee7c03fe67a87dfc52e846aa625ea hash_algorithm sha1 url - https://github.com/secondlife/3p-libpng/releases/download/v1.6.43-r2/libpng-1.6.43-r2-windows64-10329429325.tar.zst + https://github.com/secondlife/3p-libpng/releases/download/v1.6.44-r2/libpng-1.6.44-r2-windows64-13246065198.tar.zst name windows64 @@ -1267,7 +1271,7 @@ copyright Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson version - 1.6.43-r2 + 1.6.44-r2 name libpng description @@ -1312,11 +1316,11 @@ archive hash - b2bf9adc84841b6fcf48d4c00787b221607cdea3 + 372c92936d940b1cfb5ba34310691d4bb435c161 hash_algorithm sha1 url - https://github.com/secondlife/3p-libxml2/releases/download/v2.13.3-r1/libxml2-2.13.3-r1-darwin64-10329675166.tar.zst + https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-darwin64-13246071272.tar.zst name darwin64 @@ -1326,11 +1330,11 @@ archive hash - 6ab8108ea0a42e0bd462568c495e5ce5c4cdc0ff + ba6fbc34112b1acab1c8615dcd13de983f3678d3 hash_algorithm sha1 url - https://github.com/secondlife/3p-libxml2/releases/download/v2.13.3-r1/libxml2-2.13.3-r1-linux64-10329675166.tar.zst + https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-linux64-13246071272.tar.zst name linux64 @@ -1340,11 +1344,11 @@ archive hash - 5181bd267de3ad4466227f91c7e2cbed7e8b85d9 + 71968c4b621636e8ae0c5680e631f4aa67561944 hash_algorithm sha1 url - https://github.com/secondlife/3p-libxml2/releases/download/v2.13.3-r1/libxml2-2.13.3-r1-windows64-10329675166.tar.zst + https://github.com/secondlife/3p-libxml2/releases/download/v2.13.5-r2/libxml2-2.13.5-r2-windows64-13246071272.tar.zst name windows64 @@ -1357,7 +1361,7 @@ copyright Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved. version - 2.13.3-r1 + 2.13.5-r2 name libxml2 description @@ -1395,15 +1399,6 @@ llca - copyright - Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project. - - license - mit - license_file - LICENSES/ca-license.txt - name - llca platforms common @@ -1421,8 +1416,17 @@ common + license + mit + license_file + LICENSES/ca-license.txt + copyright + Copyright (c) 2016, Linden Research, Inc.; data provided by the Mozilla NSS Project. + version 202407221423.0 + name + llca llphysicsextensions_source @@ -1435,11 +1439,11 @@ creds github hash - 9e59c93c7110e87b4ff3db330f11a23c50e5000f + 7facda95e2f00c260513f3d4db42588fa8ba703c hash_algorithm sha1 url - https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910560 + https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289774 name darwin64 @@ -1451,11 +1455,11 @@ creds github hash - 7ed994db5bafa9a7ad09a1b53da850a84715c65e + 01d08f13c7bc8d1b95b0330fa6833b7d8274e4d0 hash_algorithm sha1 url - https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910561 + https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289775 name linux64 @@ -1467,11 +1471,11 @@ creds github hash - 66824c02e0e5eabbfbe37bfb173360195f89697c + 6d00345c7d3471bc5f7c1218e014dd0f1a2c069b hash_algorithm sha1 url - https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910562 + https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289778 name windows64 @@ -1484,7 +1488,7 @@ copyright Copyright (c) 2010, Linden Research, Inc. version - 1.0.66e6919 + 1.0.11137145495 name llphysicsextensions_source @@ -1627,42 +1631,42 @@ archive hash - d79631d845e2b5e4a9e6f6b660310795fd49023e + 874a7d2bc843554aa4facd03b3a6d681f2b5150c hash_algorithm sha1 url - https://github.com/secondlife/3p-meshoptimizer/releases/download/v210-r2/meshoptimizer-210.0.0-r2-darwin64-10341021290.tar.zst + https://github.com/secondlife/3p-meshoptimizer/releases/download/v220-r1/meshoptimizer-220.0.0-r1-darwin64-11968851109.tar.zst name darwin64 - windows64 + linux64 archive hash - 024ce689a6f13e66d0c7e431ac34071434e2365a + 31a537f1a3d38ef85443214315111dd56a534d9a hash_algorithm sha1 url - https://github.com/secondlife/3p-meshoptimizer/releases/download/v210-r2/meshoptimizer-210.0.0-r2-windows64-10341021290.tar.zst + https://github.com/secondlife/3p-meshoptimizer/releases/download/v220-r1/meshoptimizer-220.0.0-r1-linux64-11968851109.tar.zst name - windows64 + linux64 - linux64 + windows64 archive hash - c947107c0aca46e94e22f66328a3cbbd01d99b36 + 6fd727a9ccb3e7a6c6b4ffef8179e266c032eb3e hash_algorithm sha1 url - https://github.com/secondlife/3p-meshoptimizer/releases/download/v210-r2/meshoptimizer-210.0.0-r2-linux64-10341021290.tar.zst + https://github.com/secondlife/3p-meshoptimizer/releases/download/v220-r1/meshoptimizer-220.0.0-r1-windows64-11968851109.tar.zst name - linux64 + windows64 license @@ -1672,7 +1676,7 @@ copyright Copyright (c) 2016-2021 Arseny Kapoulkine version - 210.0.0-r2 + 220.0.0-r1 name meshoptimizer canonical_repo @@ -1751,11 +1755,11 @@ archive hash - 6bedaa9d770ef0ae6147f49a26fc3209fde9cb80 + b628d088e1f368a0cd51a6b66292aaf9a025e2d4 hash_algorithm sha1 url - https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r1/minizip_ng-4.0.7-r1-darwin64-10324657515.tar.zst + https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-darwin64-13246046977.tar.zst name darwin64 @@ -1765,11 +1769,11 @@ archive hash - ce2c91b8c4f89af252ce1b6a96af6985fe54f509 + 492ce9175b730d43df63821c4481685e035af623 hash_algorithm sha1 url - https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r1/minizip_ng-4.0.7-r1-linux64-10324657515.tar.zst + https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-linux64-13246046977.tar.zst name linux64 @@ -1779,11 +1783,11 @@ archive hash - 9cee9d85f9a7c6fb051125775f0122a926da5cc9 + 58773e707ff3490822b7b8217d7729ade2186632 hash_algorithm sha1 url - https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r1/minizip_ng-4.0.7-r1-windows64-10324657515.tar.zst + https://github.com/secondlife/3p-minizip-ng/releases/download/v4.0.7-r3/minizip_ng-4.0.7-r3-windows64-13246046977.tar.zst name windows64 @@ -1796,7 +1800,7 @@ copyright This project uses the zlib license. Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler version - 4.0.7-r1 + 4.0.7-r3 name minizip-ng canonical_repo @@ -1869,11 +1873,11 @@ archive hash - 3f3374a5d97803bf78acf20847c2900c7d68ce2b + f45ea5a42d6a419f9b605dd3f976fbcb3850d736 hash_algorithm sha1 url - https://github.com/secondlife/3p-nghttp2/releases/download/v1.62.1/nghttp2-1.62.1-darwin64-10329456052.tar.zst + https://github.com/secondlife/3p-nghttp2/releases/download/v1.64.0-r2/nghttp2-1.64.0-r1-darwin64-13184359419.tar.zst name darwin64 @@ -1883,11 +1887,11 @@ archive hash - bd9c211f9f53c04821f0ab0e1268a691926331b6 + c6e450fa41f24f1b4103d2006d706595f2a36c59 hash_algorithm sha1 url - https://github.com/secondlife/3p-nghttp2/releases/download/v1.62.1/nghttp2-1.62.1-linux64-10329456052.tar.zst + https://github.com/secondlife/3p-nghttp2/releases/download/v1.64.0-r2/nghttp2-1.64.0-r1-linux64-13184359419.tar.zst name linux64 @@ -1897,11 +1901,11 @@ archive hash - c23e25a7c47f5233f543a90f1a9ccf4da9282379 + 3bd92f892e155104740570fe244ea4dbb0b57d4b hash_algorithm sha1 url - https://github.com/secondlife/3p-nghttp2/releases/download/v1.62.1/nghttp2-1.62.1-windows64-10329456052.tar.zst + https://github.com/secondlife/3p-nghttp2/releases/download/v1.64.0-r2/nghttp2-1.64.0-r1-windows64-13184359419.tar.zst name windows64 @@ -1915,7 +1919,7 @@ Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors version - 1.62.1 + 1.64.0-r1 name nghttp2 description @@ -1964,11 +1968,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 3abb5d21655aeca9d6a4de37704e8475821c28d9 + 68657c5c161c3fe8ff64eac3787172fcb06da972 hash_algorithm sha1 url - https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7-r1/ogg_vorbis-1.3.5-1.3.7.10341271136-darwin64-10341271136.tar.zst + https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7-r2/ogg_vorbis-1.3.5-1.3.7.11968798109-darwin64-11968798109.tar.zst name darwin64 @@ -1978,11 +1982,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - d89dff615c51b46ebdb3d42ac6bd9e0faae5ddf1 + 9a6ffad7b4186a158c019c5a5a5d7b8badb441da hash_algorithm sha1 url - https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7-r1/ogg_vorbis-1.3.5-1.3.7.10341271136-linux64-10341271136.tar.zst + https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7-r2/ogg_vorbis-1.3.5-1.3.7.11968798109-linux64-11968798109.tar.zst name linux64 @@ -1992,11 +1996,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 0dc0f5334d1c882d5d7bce6d2cfaecf2f7ab1ae6 + 5f4cbb928ebfe774a9c07d3f2c255fd38bd6b4d6 hash_algorithm sha1 url - https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7-r1/ogg_vorbis-1.3.5-1.3.7.10341271136-windows64-10341271136.tar.zst + https://github.com/secondlife/3p-ogg_vorbis/releases/download/v1.3.5-1.3.7-r2/ogg_vorbis-1.3.5-1.3.7.11968798109-windows64-11968798109.tar.zst name windows64 @@ -2009,7 +2013,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2002, Xiph.org Foundation version - 1.3.5-1.3.7.10341271136 + 1.3.5-1.3.7.11968798109 name ogg_vorbis description @@ -2024,7 +2028,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com) version - 0.3 + 0.14.11968684513 name open-libndofdev description @@ -2084,7 +2088,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (C) 1999-2007 by authors. version - 1.23.1 + 1.24.2-r1 name openal description @@ -2099,11 +2103,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 76444e37be0cfccdbb5921370ba150ded2bf3c59 + 94a72c6ddbfb23796ce913c55bc47c128542a582 hash_algorithm sha1 url - https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.2-r1/openjpeg-2.5.2.10604495243-darwin64-10604495243.tar.zst + https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.3-r1/openjpeg-2.5.3.15590356935-darwin64-15590356935.tar.zst name darwin64 @@ -2113,11 +2117,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 6bd289a9c4564b80369ce40ecbb24a213c2732ff + 751172af405f4a47a3aebb37729d62229cab6c07 hash_algorithm sha1 url - https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.2-r1/openjpeg-2.5.2.10604495243-linux64-10604495243.tar.zst + https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.3-r1/openjpeg-2.5.3.15590356935-linux64-15590356935.tar.zst name linux64 @@ -2127,11 +2131,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 5e6e0180adc01e07438cb98daec96543b5d85019 + 8aab9cf250dfee252386e1c79b5205e6d3b3e19e hash_algorithm sha1 url - https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.2-r1/openjpeg-2.5.2.10604495243-windows64-10604495243.tar.zst + https://github.com/secondlife/3p-openjpeg/releases/download/v2.5.3-r1/openjpeg-2.5.3.15590356935-windows64-15590356935.tar.zst name windows64 @@ -2144,7 +2148,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium; Copyright (c) 2002-2007, Professor Benoit Macq; Copyright (c) 2001-2003, David Janssens; Copyright (c) 2002-2003, Yannick Verschueren; Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe; Copyright (c) 2005, Herve Drolon, FreeImage Team; Copyright (c) 2006-2007, Parvatha Elangovan; Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>; Copyright (c) 2010-2011, Kaori Hagihara; Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France; Copyright (c) 2012, CS Systemes d'Information, France; version - 2.5.0.ea12248 + 2.5.3.15590356935 name openjpeg description @@ -2159,11 +2163,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - a20277991043a4a00fb8280a27a41fbd87c4b840 + 157193699127ac5056c5fc1a410f9c98d39731e2 hash_algorithm sha1 url - https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r1/openssl-1.1.1w-darwin64-10329796904.tar.zst + https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r3/openssl-1.1.1w-r3-darwin64-13246054022.tar.zst name darwin64 @@ -2173,11 +2177,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 0f2cd519431b11cacf85971c66c49e5b4d26c56f + 2e29c127dbd002d64ae55bc000f8b6ed0249fad7 hash_algorithm sha1 url - https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r1/openssl-1.1.1w-linux64-10329796904.tar.zst + https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r3/openssl-1.1.1w-r3-linux64-13246054022.tar.zst name linux64 @@ -2187,11 +2191,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 5e396eedf1492d18126b7281367123c1d64b89aa + ae9ced89051e03a99628c99b9ac78530fdea1e5a hash_algorithm sha1 url - https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r1/openssl-1.1.1w-windows64-10329796904.tar.zst + https://github.com/secondlife/3p-openssl/releases/download/v1.1.1w-r3/openssl-1.1.1w-r3-windows64-13246054022.tar.zst name windows64 @@ -2204,7 +2208,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved; Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) version - 1.1.1w + 1.1.1w-r3 name openssl description @@ -2330,16 +2334,42 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors description Vivox SDK components - threejs + sse2neon - copyright - Copyright © 2010-2021 three.js authors + platforms + + common + + archive + + hash + e51fb1d24836d897ce90b8a72010635915b959d6 + hash_algorithm + sha1 + url + https://github.com/secondlife/3p-sse2neon/releases/download/v1.8.0/sse2neon-1.8.0-common-17657389472.tar.zst + + name + common + + license MIT license_file - LICENSES/THREEJS_LICENSE.txt + LICENSES/sse2neon.txt + copyright + Copyright (c) 2015-2024 SSE2NEON Contributors. + version + 1.8.0 name - threejs + sse2neon + canonical_repo + https://github.com/secondlife/3p-sse2neon + description + A translator from Intel SSE intrinsics to Arm/Aarch64 NEON implementation + + threejs + platforms common @@ -2357,8 +2387,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors common + license + MIT + license_file + LICENSES/THREEJS_LICENSE.txt + copyright + Copyright © 2010-2021 three.js authors version 0.132.2 + name + threejs tinygltf @@ -2407,11 +2445,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 226225ec049826c35adc5e897e0398ed64d4bedb + 0c3d01b7e9e39c23f0f40c56a1a04d1fba08ead0 hash_algorithm sha1 url - https://github.com/secondlife/3p-tracy/releases/download/v0.11.0%2Br1/tracy-v0.11.0.10376230034-darwin64-10376230034.tar.zst + https://github.com/secondlife/3p-tracy/releases/download/v0.11.1-r1/tracy-v0.11.1.11706699176-darwin64-11706699176.tar.zst name darwin64 @@ -2421,11 +2459,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 8c5429d1a1486f40cf7e5e88a232222d1fa4f78e + b46cef5646a8d0471ab6256fe5119220fa238772 hash_algorithm sha1 url - https://github.com/secondlife/3p-tracy/releases/download/v0.11.0%2Br1/tracy-v0.11.0.10376230034-windows64-10376230034.tar.zst + https://github.com/secondlife/3p-tracy/releases/download/v0.11.1-r1/tracy-v0.11.1.11706699176-windows64-11706699176.tar.zst name windows64 @@ -2435,11 +2473,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - ed0664a009aba1dcf1246d845839f524e857162e + beab04c9ea6036b1851a485b65c66cf6a38f0be4 hash_algorithm sha1 url - https://github.com/secondlife/3p-tracy/releases/download/v0.11.0%2Br1/tracy-v0.11.0.10376230034-linux64-10376230034.tar.zst + https://github.com/secondlife/3p-tracy/releases/download/v0.11.1-r1/tracy-v0.11.1.11706699176-linux64-11706699176.tar.zst name linux64 @@ -2452,7 +2490,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2017-2024, Bartosz Taudul (wolf@nereid.pl) version - v0.11.0.10376230034 + v0.11.1.11706699176 name tracy canonical_repo @@ -2594,14 +2632,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors vlc-bin - copyright - Copyright (C) 1998-2016 VLC authors and VideoLAN - license - GPL2 - license_file - LICENSES/vlc.txt - name - vlc-bin platforms darwin64 @@ -2609,11 +2639,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - f13c82042ef8311e57dd75a3b2bda02d70f711b5 + 6d72afd5cc21446c65899615909b1f09f155585d hash_algorithm sha1 url - https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.21.e60ee26/vlc_bin-3.0.21.10218721728-darwin64-10218721728.tar.zst + https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.21.296d9f4/vlc_bin-3.0.21.11968962952-darwin64-11968962952.tar.zst name darwin64 @@ -2623,18 +2653,26 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - bd995441c1a229ed1432ddd837d7d1663b8c5548 + f986e6e93acf8a32a8be5b638f0bd0e2e07d7507 hash_algorithm sha1 url - https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.21.e60ee26/vlc_bin-3.0.21.10218721728-windows64-10218721728.tar.zst + https://github.com/secondlife/3p-vlc-bin/releases/download/v3.0.21.296d9f4/vlc_bin-3.0.21.11968962952-windows64-11968962952.tar.zst name windows64 + license + GPL2 + license_file + LICENSES/vlc.txt + copyright + Copyright (C) 1998-2016 VLC authors and VideoLAN version - 3.0.21.10218721728 + 3.0.21.11968962952 + name + vlc-bin vulkan_gltf @@ -2679,11 +2717,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 3570b6442d472cd97bad8622c2ec2571d72218a0 + 43c5f93517794aeade550e4266b959d1f0cfcb7f hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.72-test/webrtc-m114.5735.08.72-test.10444682919-darwin64-10444682919.tar.zst + https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-darwin64-17630578914.tar.zst name darwin64 @@ -2693,11 +2731,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - eadf6aa99313940ded11801d42c11375669f1628 + efc5b176d878cfc16b8f82445d82ddb96815b6ab hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.72-test/webrtc-m114.5735.08.72-test.10444682919-linux64-10444682919.tar.zst + https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-linux64-17630578914.tar.zst name linux64 @@ -2707,11 +2745,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 0081fd35290adbc8e66dd366535fb6cd8a966f1e + 1e36f100de32c7c71325497a672fb1659b3f206d hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.72-test/webrtc-m114.5735.08.72-test.10444682919-windows64-10444682919.tar.zst + https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-windows64-17630578914.tar.zst name windows64 @@ -2724,7 +2762,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2011, The WebRTC project authors. All rights reserved. version - m114.5735.08.72-test.10444682919 + m137.7151.04.20-universal.17630578914 name webrtc vcs_branch @@ -2777,11 +2815,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 3a6593c71c59ace76d1349483759fcde4b719a76 + e363e3b889c52fda7601d7aeaa9832307034651e hash_algorithm sha1 url - https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-darwin64-10324415171.tar.zst + https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-darwin64-13183604450.tar.zst name darwin64 @@ -2791,11 +2829,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - fbadeb0b8c771cb06c0055c9fab6d40c6764dacd + 3cdd52f7fb3691789d50f0b40ed6f5642321ff32 hash_algorithm sha1 url - https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-linux64-10324415171.tar.zst + https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-linux64-13183604450.tar.zst name linux64 @@ -2805,11 +2843,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 0094031715662be626f5106ff6c814f4fc3dacfa + e802a28139328bb2421ad39e13d996d350d8106d hash_algorithm sha1 url - https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.1-r2/zlib_ng-2.2.1-r2-windows64-10324415171.tar.zst + https://github.com/secondlife/3p-zlib-ng/releases/download/v2.2.3-r1/zlib_ng-2.2.3-dev0.g8aa13e3.d20250206-windows64-13183604450.tar.zst name windows64 @@ -2822,7 +2860,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler version - 2.2.1-r2 + 2.2.3-dev0.g8aa13e3.d20250206 name zlib-ng canonical_repo @@ -2832,16 +2870,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors tinyexr - copyright - Copyright (c) 2014 - 2021, Syoyo Fujita and many contributors. - description - tinyexr import library - license - 3-clause BSD - license_file - LICENSES/tinyexr_license.txt - name - tinyexr platforms common @@ -2859,16 +2887,26 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors common - source_type - git + license + 3-clause BSD + license_file + LICENSES/tinyexr_license.txt + copyright + Copyright (c) 2014 - 2021, Syoyo Fujita and many contributors. + version + 1.0.9-5e8947c + name + tinyexr vcs_branch dependabot/github_actions/secondlife/action-autobuild-4 vcs_revision 4dc4d1d90d82a22843e2adf5130f9ecb5ee5769e vcs_url https://github.com/secondlife/3p-tinyexr - version - 1.0.9-5e8947c + description + tinyexr import library + source_type + git discord_sdk @@ -2928,6 +2966,46 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors description Discord Social SDK + websocketpp + + platforms + + common + + archive + + hash + 9b02492bbc5effd8afca1bb7c95110d43a8f75da + hash_algorithm + sha1 + url + https://github.com/secondlife/3p-websocketpp/releases/download/v0.8.2/websocketpp-0.8.2.17134644226-common-17134644226.tar.zst + + name + common + + + license + websocketpp + license_file + LICENSES/websocketpp.txt + copyright + Copyright (c) 2014, Peter Thorson + version + 0.8.2.17134644226 + name + websocketpp + vcs_branch + refs/tags/v0.8.2 + vcs_revision + bdcf1453101976fc4dc26a62c87bc98c12e9c6dc + vcs_url + git://github.com/secondlife/3p-websocketpp.git + canonical_repo + https://github.com/secondlife/3p-websocketpp + description + WebSocket++ is a C++ header only library for interacting with WebSocket servers and clients. + package_description @@ -3149,7 +3227,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors build_directory - build-darwin-x86_64 + build-darwin-universal name darwin64 diff --git a/build.sh b/build.sh index eb81ff319a4..36e332cf42c 100755 --- a/build.sh +++ b/build.sh @@ -40,7 +40,7 @@ retry_cmd() build_dir_Darwin() { - echo build-darwin-x86_64 + echo build-darwin-universal } build_dir_Linux() @@ -158,6 +158,7 @@ pre_build() if [[ "$arch" == "Darwin" ]] then + HAVOK=OFF SIGNING=("-DENABLE_SIGNING:BOOL=YES" \ "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.") fi @@ -387,7 +388,7 @@ do if `cat "$build_dir/build_ok"` then case "$variant" in - Release) + Release*) if [ -r "$build_dir/autobuild-package.xml" ] then begin_section "Autobuild metadata" diff --git a/doc/external-editor-json-rpc.md b/doc/external-editor-json-rpc.md new file mode 100644 index 00000000000..b8c7fa69e32 --- /dev/null +++ b/doc/external-editor-json-rpc.md @@ -0,0 +1,464 @@ +# Viewer to External Editor JSON-RPC
Message Interfaces Documentation + +This document describes all the message interfaces defined in for WebSocket communication between the Second Life viewer and an external editor such as a VSCode extension. + +## Table of Contents + +- [Usage Flow](#usage-flow) +- [JSON-RPC Method Summary](#json-rpc-method-summary) +- [Session Management Interfaces](#session-management-interfaces) + - [SessionHandshake](#sessionhandshake) + - [SessionHandshakeResponse](#sessionhandshakeresponse) + - [Session OK](#session-ok) + - [SessionDisconnect](#sessiondisconnect) +- [Language and Syntax Interfaces](#language-and-syntax-interfaces) + - [SyntaxChange](#syntaxchange) + - [Language Syntax ID Request](#language-syntax-id-request) + - [Language Syntax Request](#language-syntax-request) +- [Script Subscription Interfaces](#script-subscription-interfaces) + - [ScriptSubscribe](#scriptsubscribe) + - [ScriptSubscribeResponse](#scriptsubscriberesponse) + - [ScriptUnsubscribe](#scriptunsubscribe) +- [Compilation Interfaces](#compilation-interfaces) + - [CompilationError](#compilationerror) + - [CompilationResult](#compilationresult) +- [Runtime Event Interfaces](#runtime-event-interfaces) + - [RuntimeDebug](#runtimedebug) + - [RuntimeError](#runtimeerror) +- [Handler and Configuration Interfaces](#handler-and-configuration-interfaces) + - [WebSocketHandlers](#websockethandlers) + - [ClientInfo](#clientinfo) + +## Usage Flow + +1. **Connection Establishment:** + + - Viewer sends `session.handshake` notification with `SessionHandshake` data + - Extension responds with `SessionHandshakeResponse` + - Viewer confirms with `session.ok` notification + +2. **Language Information Exchange:** + + - Extension makes `language.syntax.id` call to get current syntax version + - Extension makes `language.syntax` calls with different `kind` parameters to get specific language data + - Viewer responds with `LanguageInfo` data containing the requested information + +3. **Script Subscription Management:** + + - Extension makes `script.subscribe` call with `ScriptSubscribe` data to request live synchronization for a script + - Viewer responds with `ScriptSubscribeResponse` indicating success or failure + - When subscription needs to be terminated, viewer sends `script.unsubscribe` notification with `ScriptUnsubscribe` data + - Extension handles unsubscription by cleaning up local script tracking + +4. **Runtime Events:** + + - Viewer sends `language.syntax.change` notification with `SyntaxChange` when language changes + - Viewer sends `script.compiled` notification with `CompilationResult` after script compilation + - Viewer sends `runtime.debug` notification with `RuntimeDebug` for debug messages during script execution + - Viewer sends `runtime.error` notification with `RuntimeError` when runtime errors occur + +5. **Connection Termination:** + - Either side can send `session.disconnect` notification with `SessionDisconnect` data + - Connection is closed gracefully + +## JSON-RPC Method Summary + +| Method | Direction | Type | Interface/Parameters | +| ------------------------------- | ------------------ | ------------ | -------------------------- | +| `session.handshake` | Viewer → Extension | Notification | `SessionHandshake` | +| `session.handshake` (response) | Extension → Viewer | Response | `SessionHandshakeResponse` | +| `session.ok` | Viewer → Extension | Notification | _(no interface)_ | +| `session.disconnect` | Bidirectional | Notification | `SessionDisconnect` | +| `script.subscribe` | Extension → Viewer | Call | `ScriptSubscribe` | +| `script.subscribe` (response) | Viewer → Extension | Response | `ScriptSubscribeResponse` | +| `script.unsubscribe` | Viewer → Extension | Notification | `ScriptUnsubscribe` | +| `language.syntax.id` | Extension → Viewer | Call | _(no parameters)_ | +| `language.syntax.id` (response) | Viewer → Extension | Response | `{ id: string }` | +| `language.syntax` | Extension → Viewer | Call | `{ kind: string }` | +| `language.syntax` (response) | Viewer → Extension | Response | `LanguageInfo` | +| `language.syntax.change` | Viewer → Extension | Notification | `SyntaxChange` | +| `script.compiled` | Viewer → Extension | Notification | `CompilationResult` | +| `runtime.debug` | Viewer → Extension | Notification | `RuntimeDebug` | +| `runtime.error` | Viewer → Extension | Notification | `RuntimeError` | + +## Session Management Interfaces + +### SessionHandshake + +**JSON-RPC Method:** `session.handshake` (notification from viewer) + +The initial handshake message sent by the viewer to establish a connection. + +```typescript +interface SessionHandshake { + server_version: "1.0.0"; + protocol_version: "1.0"; + viewer_name: string; + viewer_version: string; + agent_id: string; + agent_name: string; + challenge?: string; + languages: string[]; + syntax_id: string; + features: { [feature: string]: boolean }; +} +``` + +**Fields:** + +- `server_version`: Fixed version "1.0.0" indicating the server API version +- `protocol_version`: Fixed version "1.0" for the communication protocol +- `viewer_name`: Name of the Second Life viewer application +- `viewer_version`: Version string of the viewer +- `agent_id`: Unique identifier for the user/agent +- `agent_name`: Human-readable name of the agent +- `challenge` (optional): Security challenge string for authentication +- `languages`: Array of supported scripting languages (e.g., ["lsl", "luau"]) +- `syntax_id`: Current active syntax/language identifier +- `features`: Dictionary of feature flags indicating viewer capabilities + +### SessionHandshakeResponse + +**JSON-RPC Method:** Response to `session.handshake` + +The response sent by the VS Code extension to complete the handshake. + +```typescript +interface SessionHandshakeResponse { + client_name: string; + client_version: "1.0"; + protocol_version: string; + challenge_response?: string; + languages: string[]; + features: { [feature: string]: boolean }; +} +``` + +**Fields:** + +- `client_name`: Name of the client (VS Code extension) +- `client_version`: Fixed version "1.0" of the client +- `protocol_version`: Protocol version the client supports +- `challenge_response` (optional): Response to the security challenge if provided +- `languages`: Array of languages supported by the client +- `features`: Dictionary of features supported by the client + +### Session OK + +**JSON-RPC Method:** `session.ok` (notification from viewer) + +Confirmation notification sent by the viewer after successful handshake completion. This interface has no defined structure as it appears to be a simple confirmation message. + +### SessionDisconnect + +**JSON-RPC Method:** `session.disconnect` (notification, bidirectional) + +Message sent when terminating the connection. + +```typescript +interface SessionDisconnect { + reason: number; + message: string; +} +``` + +**Fields:** + +- `reason`: Numeric code indicating the reason for disconnection +- `message`: Human-readable description of the disconnect reason + +## Language and Syntax Interfaces + +### SyntaxChange + +**JSON-RPC Method:** `language.syntax.change` (notification from viewer) + +Notification sent when the active language syntax changes in the viewer. + +```typescript +interface SyntaxChange { + id: string; +} +``` + +**Fields:** + +- `id`: Identifier for the new syntax/language + +### Language Syntax ID Request + +**JSON-RPC Method:** `language.syntax.id` (call from extension to viewer) + +Requests the current active language syntax identifier from the viewer. This method takes no parameters. + +**Response:** Returns an object with an `id` field containing the current syntax identifier. + +### Language Syntax Request + +**JSON-RPC Method:** `language.syntax` (call from extension to viewer) + +Requests detailed syntax information for a specific language kind. + +**Parameters:** + +```typescript +{ + kind: string; // The type of syntax information requested +} +``` + +**Fields:** + +- `kind`: The type of syntax information to retrieve (e.g., "functions", "constants", "events", "types.luau") + +**Response:** Returns `LanguageInfo` data containing the requested syntax information: + +```typescript +interface LanguageInfo { + id: string; + lslDefs?: { + controls?: any; + types?: any; + constants?: { [name: string]: ConstantDef }; + events?: { [name: string]: FunctionDef }; + functions?: { [name: string]: FunctionDef }; + }; + luaDefs?: { + modules?: { [name: string]: TypeDef }; + classes?: { [name: string]: TypeDef }; + aliases?: { [name: string]: TypeDef }; + functions?: { [name: string]: FunctionDef }; + }; +} +``` + +**Response Fields:** + +- `id`: Version identifier for the language syntax +- `lslDefs` (optional): LSL-specific language definitions containing: + - `controls` (optional): Control flow and language constructs + - `types` (optional): LSL type definitions + - `constants` (optional): Object containing constant definitions keyed by constant name + - `events` (optional): Object containing event definitions keyed by event name + - `functions` (optional): Object containing function definitions keyed by function name +- `luaDefs` (optional): Lua-specific language definitions containing: + - `modules` (optional): Module type definitions keyed by module name + - `classes` (optional): Class type definitions keyed by class name + - `aliases` (optional): Type alias definitions keyed by alias name + - `functions` (optional): Function definitions keyed by function name + +The specific sections returned depend on the `kind` parameter and the active language context. + +## Script Subscription Interfaces + +### ScriptSubscribe + +**JSON-RPC Method:** `script.subscribe` (call from extension to viewer) + +Requests subscription to a script for live synchronization between the editor and viewer. + +```typescript +interface ScriptSubscribe { + script_id: string; + script_name: string; + script_language: string; +} +``` + +**Fields:** + +- `script_id`: Unique identifier for the script to subscribe to +- `script_name`: Display name of the script file +- `script_language`: Programming language of the script (e.g., "lsl", "luau") + +### ScriptSubscribeResponse + +**JSON-RPC Method:** Response to `script.subscribe` + +Response from the viewer indicating whether script subscription was successful. + +```typescript +interface ScriptSubscribeResponse { + script_id: string; + success: boolean; + status: number; + object_id?: string; + object_name?: string; + item_id?: string; + message?: string; +} +``` + +**Fields:** + +- `script_id`: The script identifier that was subscribed to +- `success`: Whether the subscription was successful +- `status`: Numeric status code indicating the result +- `object_id` (optional): The in-world ID of the object containing the script +- `object_name` (optional): The name of the object containing the script. +- `message` (optional): Additional information about the subscription result + +### ScriptUnsubscribe + +**JSON-RPC Method:** `script.unsubscribe` (notification from viewer) + +Notification sent by the viewer when a script subscription should be terminated. + +```typescript +interface ScriptUnsubscribe { + script_id: string; +} +``` + +**Fields:** + +- `script_id`: Unique identifier for the script to unsubscribe from + +## Compilation Interfaces + +### CompilationError + +Individual compilation error record. + +```typescript +interface CompilationError { + row: number; + column: number; + level: "ERROR"; + message: string; +} +``` + +**Fields:** + +- `row`: Line number where the error occurred (0-based or 1-based depending on context) +- `column`: Column position of the error +- `level`: Severity level (currently only "ERROR" is defined) +- `message`: Error description + +### CompilationResult + +**JSON-RPC Method:** `script.compiled` (notification from viewer) + +Result of a compilation operation in the viewer. + +```typescript +interface CompilationResult { + script_id: string; + success: boolean; + running: boolean; + errors?: CompilationError[]; +} +``` + +**Fields:** + +- `script_id`: Unique identifier for the script that was compiled +- `success`: Whether the compilation was successful +- `running`: Whether the compiled script is currently running +- `errors` (optional): Array of compilation errors if any occurred + +## Runtime Event Interfaces + +### RuntimeDebug + +**JSON-RPC Method:** `runtime.debug` (notification from viewer) + +Debug message notification sent by the viewer during script execution. + +```typescript +interface RuntimeDebug { + script_id: string; + object_id: string; + object_name: string; + message: string; +} +``` + +**Fields:** + +- `script_id`: Unique identifier for the script generating the debug message +- `object_id`: Unique identifier for the object containing the script +- `object_name`: Human-readable name of the object +- `message`: The debug message content + +### RuntimeError + +**JSON-RPC Method:** `runtime.error` (notification from viewer) + +Runtime error notification sent by the viewer when a script encounters an error during execution. + +```typescript +interface RuntimeError { + script_id: string; + object_id: string; + object_name: string; + message: string; + error: string; + line: number; + stack?: string[]; +} +``` + +**Fields:** + +- `script_id`: Unique identifier for the script that encountered the error +- `object_id`: Unique identifier for the object containing the script +- `object_name`: Human-readable name of the object +- `message`: Error message description +- `error`: Specific error type or code +- `line`: Line number where the error occurred +- `stack` (optional): Stack trace information if available + +## Handler and Configuration Interfaces + +### WebSocketHandlers + +Event handler interface for WebSocket events. + +```typescript +interface WebSocketHandlers { + onHandshake?: (message: SessionHandshake) => SessionHandshakeResponse; + onHandshakeOk?: () => void; + onDisconnect?: (message: SessionDisconnect) => void; + onSubscribe?: (message: ScriptSubscribe) => ScriptSubscribeResponse; + onUnsubscribe?: (message: ScriptUnsubscribe) => void; + onSyntaxChange?: (message: SyntaxChange) => void; + onConnectionClosed?: () => void; + onCompilationResult?: (message: CompilationResult) => void; + onRuntimeDebug?: (message: RuntimeDebug) => void; + onRuntimeError?: (message: RuntimeError) => void; +} +``` + +**Methods:** + +- `onHandshake`: Handler for initial handshake message, returns handshake response +- `onHandshakeOk`: Handler called when handshake is successfully completed +- `onDisconnect`: Handler for disconnect notifications +- `onSubscribe`: Handler for script subscription requests from viewer, returns subscription response +- `onUnsubscribe`: Handler for script unsubscription notifications from viewer +- `onSyntaxChange`: Handler for syntax change notifications +- `onConnectionClosed`: Handler called when connection is closed +- `onCompilationResult`: Handler for compilation result notifications +- `onRuntimeDebug`: Handler for runtime debug message notifications +- `onRuntimeError`: Handler for runtime error notifications + +### ClientInfo + +Client information used in handshake responses. + +```typescript +interface ClientInfo { + scriptName: string; + scriptId: string; + extension: string; +} +``` + +**Fields:** + +- `scriptName`: Name of the script being edited +- `scriptId`: Unique identifier for the script +- `extension`: File extension or script type + diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 3170dbc180c..6504002dd98 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -10,7 +10,13 @@ ## Nicky: Ideally we want at least 3.21 for good preset support ## We're not there yet, but once done, there is a kludge in Linking.cmake # "if(${CMAKE_VERSION} VERSION_LESS "3.20.0")" that can also be removed -cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.16.0...4.0 FATAL_ERROR) +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.29.0") + cmake_policy(SET CMP0156 NEW) +endif() +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.31.0") + cmake_policy(SET CMP0179 NEW) +endif() set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING "The root project/makefile/solution name. Defaults to SecondLife.") @@ -33,6 +39,14 @@ if (NOT DEFINED CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 20) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) # This slows down build massively + +set(CMAKE_OPTIMIZE_DEPENDENCIES ON) + +set(CMAKE_COLOR_DIAGNOSTICS ON) + +# Speeds up cmake generation significantly in some cases +set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY ON) include(Variables) include(BuildVersion) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index c895f423624..99ea22ab4b6 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -34,7 +34,10 @@ add_compile_definitions(BOOST_BIND_GLOBAL_PLACEHOLDERS) # Force enable SSE2 instructions in GLM per the manual # https://github.com/g-truc/glm/blob/master/manual.md#section2_10 -add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_SSE2=1 GLM_ENABLE_EXPERIMENTAL=1) +add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_ENABLE_EXPERIMENTAL=1) + +# SSE2NEON throws a pointless warning when compiler optimizations are enabled +add_compile_definitions(SSE2NEON_SUPPRESS_WARNINGS=1) # Configure crash reporting set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds") @@ -78,6 +81,8 @@ if (WINDOWS) NOMINMAX # DOM_DYNAMIC # For shared library colladadom _CRT_SECURE_NO_WARNINGS # Allow use of sprintf etc + _CRT_NONSTDC_NO_DEPRECATE # Allow use of sprintf etc + _CRT_OBSOLETE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS # Disable deprecated WinSock API warnings ) add_compile_options( @@ -160,46 +165,40 @@ if (LINUX) set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}") endif (LINUX) - if (DARWIN) + # Use rpath loading on macos + set(CMAKE_MACOSX_RPATH TRUE) + # Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default set(CLANG_DISABLE_FATAL_WARNINGS OFF) set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}") - set(DARWIN_extra_cstar_flags "-Wno-unused-local-typedef -Wno-deprecated-declarations") - # Ensure that CMAKE_CXX_FLAGS has the correct -g debug information format -- - # see Variables.cmake. - string(REPLACE "-gdwarf-2" "-g${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}" - CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DARWIN_extra_cstar_flags}") - # NOTE: it's critical that the optimization flag is put in front. - # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. -## Really?? On developer machines too? -##set(ENABLE_SIGNING TRUE) -##set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.") - - # required for clang-15/xcode-15 since our boost package still uses deprecated std::unary_function/binary_function - # see https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#C++-Standard-Library - add_compile_definitions(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) -endif (DARWIN) -if (LINUX OR DARWIN) - set(GCC_WARNINGS -Wall -Wno-sign-compare -Wno-trigraphs) + # Ensure debug symbols are always generated + add_compile_options(-g --debug) # --debug is a clang synonym for -g that bypasses cmake behaviors + + # Silence GL deprecation warnings + add_compile_definitions(GL_SILENCE_DEPRECATION=1) +endif(DARWIN) - if (NOT GCC_DISABLE_FATAL_WARNINGS) - list(APPEND GCC_WARNINGS -Werror) - endif (NOT GCC_DISABLE_FATAL_WARNINGS) +if (LINUX OR DARWIN) + add_compile_options(-Wall -Wno-sign-compare -Wno-trigraphs -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable) - list(APPEND GCC_WARNINGS -Wno-reorder -Wno-non-virtual-dtor ) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + # libstdc++ headers contain deprecated declarations that fail on clang + # macOS currently has many deprecated calls + add_compile_options(-Wno-unused-local-typedef) + endif() - if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13) - list(APPEND GCC_WARNINGS -Wno-unused-but-set-variable -Wno-unused-variable ) + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + add_compile_options(-Wno-stringop-truncation -Wno-parentheses -Wno-maybe-uninitialized) endif() + if (NOT GCC_DISABLE_FATAL_WARNINGS AND NOT CLANG_DISABLE_FATAL_WARNINGS) + add_compile_options(-Werror) + endif () + add_compile_options(${GCC_WARNINGS}) add_compile_options(-m${ADDRESS_SIZE}) endif (LINUX OR DARWIN) - - diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake index 97b316c4c7c..e0807a7d19d 100644 --- a/indra/cmake/APR.cmake +++ b/indra/cmake/APR.cmake @@ -9,35 +9,25 @@ use_system_binary( apr apr-util ) use_prebuilt_binary(apr_suite) if (WINDOWS) - if (LLCOMMON_LINK_SHARED) - set(APR_selector "lib") - else (LLCOMMON_LINK_SHARED) - set(APR_selector "") - endif (LLCOMMON_LINK_SHARED) - target_link_libraries( ll::apr INTERFACE - ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apr-1.lib - ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}aprutil-1.lib - ) - target_compile_definitions( ll::apr INTERFACE APR_DECLARE_STATIC=1 APU_DECLARE_STATIC=1 API_DECLARE_STATIC=1) -elseif (DARWIN) - if (LLCOMMON_LINK_SHARED) - set(APR_selector "0.dylib") - set(APRUTIL_selector "0.dylib") - else (LLCOMMON_LINK_SHARED) - set(APR_selector "a") - set(APRUTIL_selector "a") - endif (LLCOMMON_LINK_SHARED) - - target_link_libraries( ll::apr INTERFACE - ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.${APR_selector} - ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.${APR_selector} - iconv - ) -else() - target_link_libraries( ll::apr INTERFACE - ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.a - ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.a - rt - ) + target_compile_definitions(ll::apr INTERFACE APR_DECLARE_STATIC=1 APU_DECLARE_STATIC=1 API_DECLARE_STATIC=1) endif () -target_include_directories( ll::apr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/apr-1 ) + +find_library(APR_LIBRARY + NAMES + apr-1.lib + libapr-1.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(APRUTIL_LIBRARY + NAMES + aprutil-1.lib + libaprutil-1.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::apr INTERFACE ${APR_LIBRARY} ${APRUTIL_LIBRARY}) + +if(DARWIN) + target_link_libraries(ll::apr INTERFACE iconv) +endif() + +target_include_directories(ll::apr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/apr-1) diff --git a/indra/cmake/Audio.cmake b/indra/cmake/Audio.cmake index 8c82749cabb..5a7a7ab0b52 100644 --- a/indra/cmake/Audio.cmake +++ b/indra/cmake/Audio.cmake @@ -9,23 +9,29 @@ use_system_binary(vorbis) use_prebuilt_binary(ogg_vorbis) target_include_directories( ll::vorbis SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) -if (WINDOWS) - target_link_libraries(ll::vorbis INTERFACE - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libogg.lib - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libogg.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisenc.lib - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbisenc.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisfile.lib - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbisfile.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbis.lib - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbis.lib - ) -else (WINDOWS) - target_link_libraries(ll::vorbis INTERFACE - ${ARCH_PREBUILT_DIRS_RELEASE}/libogg.a - ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisenc.a - ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisfile.a - ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbis.a - ) -endif (WINDOWS) +find_library(OGG_LIBRARY + NAMES + libogg.lib + libogg.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(VORBIS_LIBRARY + NAMES + libvorbis.lib + libvorbis.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(VORBISENC_LIBRARY + NAMES + libvorbisenc.lib + libvorbisenc.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(VORBISFILE_LIBRARY + NAMES + libvorbisfile.lib + libvorbisfile.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::vorbis INTERFACE ${VORBISENC_LIBRARY} ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY} ) diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 8c5b946753f..b57c33c3e00 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -17,40 +17,118 @@ use_prebuilt_binary(boost) set(addrsfx "-x${ADDRESS_SIZE}") if (WINDOWS) - target_link_libraries( ll::boost INTERFACE - libboost_context-mt${addrsfx} - libboost_fiber-mt${addrsfx} - libboost_filesystem-mt${addrsfx} - libboost_program_options-mt${addrsfx} - libboost_regex-mt${addrsfx} - libboost_system-mt${addrsfx} - libboost_thread-mt${addrsfx} - libboost_url-mt${addrsfx}) -elseif (LINUX) - target_link_libraries( ll::boost INTERFACE - boost_context-mt${addrsfx} - boost_fiber-mt${addrsfx} - boost_filesystem-mt${addrsfx} - boost_program_options-mt${addrsfx} - boost_regex-mt${addrsfx} - boost_signals-mt${addrsfx} - boost_system-mt${addrsfx} - boost_thread-mt${addrsfx} - boost_url-mt${addrsfx}) -elseif (DARWIN) - target_link_libraries( ll::boost INTERFACE - boost_context-mt${addrsfx} - boost_fiber-mt${addrsfx} - boost_filesystem-mt${addrsfx} - boost_program_options-mt${addrsfx} - boost_regex-mt${addrsfx} - boost_system-mt${addrsfx} - boost_thread-mt${addrsfx} - boost_url-mt${addrsfx}) + + find_library(BOOST_CONTEXT_LIBRARY + NAMES + libboost_context-mt + libboost_context-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_FIBER_LIBRARY + NAMES + libboost_fiber-mt + libboost_fiber-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_FILESYSTEM_LIBRARY + NAMES + libboost_filesystem-mt + libboost_filesystem-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_PROGRAMOPTIONS_LIBRARY + NAMES + libboost_program_options-mt + libboost_program_options-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_REGEX_LIBRARY + NAMES + libboost_regex-mt + libboost_regex-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_SYSTEM_LIBRARY + NAMES + libboost_system-mt + libboost_system-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_THREAD_LIBRARY + NAMES + libboost_thread-mt + libboost_thread-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_URL_LIBRARY + NAMES + libboost_url-mt + libboost_url-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +else (WINDOWS) + + find_library(BOOST_CONTEXT_LIBRARY + NAMES + boost_context-mt + boost_context-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_FIBER_LIBRARY + NAMES + boost_fiber-mt + boost_fiber-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_FILESYSTEM_LIBRARY + NAMES + boost_filesystem-mt + boost_filesystem-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_PROGRAMOPTIONS_LIBRARY + NAMES + boost_program_options-mt + boost_program_options-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_REGEX_LIBRARY + NAMES + boost_regex-mt + boost_regex-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_SYSTEM_LIBRARY + NAMES + boost_system-mt + boost_system-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_THREAD_LIBRARY + NAMES + boost_thread-mt + boost_thread-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(BOOST_URL_LIBRARY + NAMES + boost_url-mt + boost_url-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + endif (WINDOWS) +target_link_libraries(ll::boost INTERFACE + ${BOOST_FIBER_LIBRARY} + ${BOOST_CONTEXT_LIBRARY} + ${BOOST_FILESYSTEM_LIBRARY} + ${BOOST_PROGRAMOPTIONS_LIBRARY} + ${BOOST_REGEX_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} + ${BOOST_THREAD_LIBRARY} + ${BOOST_URL_LIBRARY}) + if (LINUX) - set(BOOST_SYSTEM_LIBRARY ${BOOST_SYSTEM_LIBRARY} rt) - set(BOOST_THREAD_LIBRARY ${BOOST_THREAD_LIBRARY} rt) + target_link_libraries(ll::boost INTERFACE rt) endif (LINUX) diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake index 9b77becf29f..e27929fa088 100644 --- a/indra/cmake/CEFPlugin.cmake +++ b/indra/cmake/CEFPlugin.cmake @@ -29,7 +29,6 @@ elseif (DARWIN) ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a ${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a ${APPKIT_LIBRARY} - "-F ${CEF_LIBRARY}" ) elseif (LINUX) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 0a00ccbb5b8..d378366e6bb 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -53,9 +53,11 @@ set(cmake_SOURCE_FILES Prebuilt.cmake PulseAudio.cmake Python.cmake + SSE2NEON.cmake TemplateCheck.cmake TinyEXR.cmake TinyGLTF.cmake + Tracy.cmake Tut.cmake UI.cmake UnixInstall.cmake @@ -64,6 +66,7 @@ set(cmake_SOURCE_FILES VisualLeakDetector.cmake LibVLCPlugin.cmake WebRTC.cmake + websocketpp.cmake xxHash.cmake ZLIBNG.cmake ) diff --git a/indra/cmake/CURL.cmake b/indra/cmake/CURL.cmake index eea0a2da623..b1595d57a89 100644 --- a/indra/cmake/CURL.cmake +++ b/indra/cmake/CURL.cmake @@ -7,19 +7,13 @@ add_library( ll::libcurl INTERFACE IMPORTED ) use_system_binary(libcurl) use_prebuilt_binary(curl) -if (WINDOWS) - target_link_libraries(ll::libcurl INTERFACE - ${ARCH_PREBUILT_DIRS_RELEASE}/libcurl.lib - ll::openssl - ll::nghttp2 - ll::zlib-ng - ) -else () - target_link_libraries(ll::libcurl INTERFACE - ${ARCH_PREBUILT_DIRS_RELEASE}/libcurl.a - ll::openssl - ll::nghttp2 - ll::zlib-ng - ) -endif () + +find_library(CURL_LIBRARY + NAMES + libcurl.lib + libcurl.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::libcurl INTERFACE ${CURL_LIBRARY} ll::openssl ll::nghttp2 ll::zlib-ng) + target_include_directories( ll::libcurl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 0153e69d5b8..680f2f3ac20 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -59,11 +59,6 @@ if(WINDOWS) openjp2.dll ) - if(LLCOMMON_LINK_SHARED) - set(release_files ${release_files} libapr-1.dll) - set(release_files ${release_files} libaprutil-1.dll) - endif() - # Filenames are different for 32/64 bit BugSplat file and we don't # have any control over them so need to branch. if (USE_BUGSPLAT) @@ -178,15 +173,6 @@ elseif(DARWIN) libndofdev.dylib ) - if(LLCOMMON_LINK_SHARED) - set(release_files ${release_files} - libapr-1.0.dylib - libapr-1.dylib - libaprutil-1.0.dylib - libaprutil-1.dylib - ) - endif() - if (TARGET ll::discord_sdk) list(APPEND release_files libdiscord_partner_sdk.dylib) endif () @@ -236,13 +222,6 @@ elseif(LINUX) libgmodule-2.0.so libgobject-2.0.so ) - - if(LLCOMMON_LINK_SHARED) - set(release_files ${release_files} - libapr-1.so.0 - libaprutil-1.so.0 - ) - endif() endif() else(WINDOWS) diff --git a/indra/cmake/EXPAT.cmake b/indra/cmake/EXPAT.cmake index 1a0b8789dc4..fe6dced7959 100644 --- a/indra/cmake/EXPAT.cmake +++ b/indra/cmake/EXPAT.cmake @@ -2,18 +2,21 @@ include(Prebuilt) include_guard() -add_library( ll::expat INTERFACE IMPORTED ) +add_library(ll::expat INTERFACE IMPORTED) use_system_binary(expat) use_prebuilt_binary(expat) + if (WINDOWS) - target_compile_definitions( ll::expat INTERFACE XML_STATIC=1) - target_link_libraries( ll::expat INTERFACE - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libexpatd.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libexpat.lib) -else () - target_link_libraries( ll::expat INTERFACE - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libexpat.a - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libexpat.a) + target_compile_definitions(ll::expat INTERFACE XML_STATIC=1) endif () -target_include_directories( ll::expat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) + +find_library(EXPAT_LIBRARY + NAMES + libexpat.lib + libexpat.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::expat INTERFACE ${EXPAT_LIBRARY}) + +target_include_directories(ll::expat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake index 563491556d2..3c635e851b1 100644 --- a/indra/cmake/FreeType.cmake +++ b/indra/cmake/FreeType.cmake @@ -9,9 +9,10 @@ use_system_binary(freetype) use_prebuilt_binary(freetype) target_include_directories( ll::freetype SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/freetype2/) -if (WINDOWS) - target_link_libraries( ll::freetype INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/freetype.lib) -else() - target_link_libraries( ll::freetype INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libfreetype.a) -endif() +find_library(FREETYPE_LIBRARY + NAMES + freetype.lib + libfreetype.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) +target_link_libraries(ll::freetype INTERFACE ${FREETYPE_LIBRARY}) diff --git a/indra/cmake/Hunspell.cmake b/indra/cmake/Hunspell.cmake index 129679febdb..b063363bc02 100644 --- a/indra/cmake/Hunspell.cmake +++ b/indra/cmake/Hunspell.cmake @@ -8,17 +8,17 @@ use_prebuilt_binary(dictionaries) add_library( ll::hunspell INTERFACE IMPORTED ) use_system_binary(hunspell) use_prebuilt_binary(libhunspell) + if (WINDOWS) target_compile_definitions( ll::hunspell INTERFACE HUNSPELL_STATIC=1) - target_link_libraries( ll::hunspell INTERFACE - debug ${ARCH_PREBUILT_DIRS_DEBUG}/libhunspell.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell.lib - ) -elseif(DARWIN) - target_link_libraries( ll::hunspell INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell-1.7.a - ) -elseif(LINUX) - target_link_libraries( ll::hunspell INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell-1.7.a - ) endif() + +find_library(HUNSPELL_LIBRARY + NAMES + libhunspell.lib + libhunspell-1.7.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::hunspell INTERFACE ${HUNSPELL_LIBRARY}) + target_include_directories( ll::hunspell SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/hunspell) diff --git a/indra/cmake/JPEG.cmake b/indra/cmake/JPEG.cmake index ade5a070ccf..f864ca7f8d1 100644 --- a/indra/cmake/JPEG.cmake +++ b/indra/cmake/JPEG.cmake @@ -8,13 +8,13 @@ add_library( ll::libjpeg INTERFACE IMPORTED ) use_system_binary(libjpeg) use_prebuilt_binary(libjpeg-turbo) -if (LINUX) - target_link_libraries( ll::libjpeg INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a) -elseif (DARWIN) - target_link_libraries( ll::libjpeg INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a) -elseif (WINDOWS) - target_link_libraries( ll::libjpeg INTERFACE - debug ${ARCH_PREBUILT_DIRS_DEBUG}/jpeg.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/jpeg.lib) -endif (LINUX) -target_include_directories( ll::libjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) + +find_library(JPEG_LIBRARY + NAMES + jpeg.lib + libjpeg.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::libjpeg INTERFACE ${JPEG_LIBRARY}) + +target_include_directories(ll::libjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 6408f1200cb..83725ffd1b8 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -92,6 +92,13 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources) target_include_directories (PROJECT_${project}_TEST_${name} PRIVATE ${LIBS_OPEN_DIR}/test ) set_target_properties(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") + if (DARWIN) + set_target_properties(PROJECT_${project}_TEST_${name} + PROPERTIES + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_RPATH "@executable_path/Resources" + ) + endif(DARWIN) # # Per-codefile additional / external project dep and lib dep property extraction @@ -225,7 +232,10 @@ FUNCTION(LL_ADD_INTEGRATION_TEST # test binaries always need to be signed for local development set_target_properties(INTEGRATION_TEST_${testname} PROPERTIES - XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-") + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-" + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_RPATH "@executable_path/Resources" + ) endif () # Add link deps to the executable diff --git a/indra/cmake/LLKDU.cmake b/indra/cmake/LLKDU.cmake index 668b07ffab4..7680ab7b542 100644 --- a/indra/cmake/LLKDU.cmake +++ b/indra/cmake/LLKDU.cmake @@ -13,14 +13,26 @@ add_library( ll::kdu INTERFACE IMPORTED ) if (USE_KDU) include(Prebuilt) use_prebuilt_binary(kdu) + if (WINDOWS) - target_link_libraries( ll::kdu INTERFACE kdu.lib) + find_library(KDU_LIBRARY + NAMES + kdu + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + else (WINDOWS) - target_link_libraries( ll::kdu INTERFACE libkdu.a) + find_library(KDU_LIBRARY + NAMES + libkdu.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + endif (WINDOWS) + target_link_libraries(ll::kdu INTERFACE ${KDU_LIBRARY}) + target_include_directories( ll::kdu SYSTEM INTERFACE ${AUTOBUILD_INSTALL_DIR}/include/kdu ${LIBS_OPEN_DIR}/llkdu ) + target_compile_definitions(ll::kdu INTERFACE KDU_NO_THREADS=1) endif (USE_KDU) diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake index d0a52ffb63e..2699f8efee1 100644 --- a/indra/cmake/LLPrimitive.cmake +++ b/indra/cmake/LLPrimitive.cmake @@ -24,26 +24,35 @@ use_prebuilt_binary(colladadom) use_prebuilt_binary(minizip-ng) # needed for colladadom use_prebuilt_binary(libxml2) -if (WINDOWS) - target_link_libraries( ll::minizip-ng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/minizip.lib ) -else() - target_link_libraries( ll::minizip-ng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libminizip.a ) -endif() +find_library(MINIZIPNG_LIBRARY + NAMES + minizip.lib + libminizip.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::minizip-ng INTERFACE ${MINIZIPNG_LIBRARY}) + +find_library(LIBXML2_LIBRARY + NAMES + libxml2.lib + libxml2.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::libxml INTERFACE ${LIBXML2_LIBRARY}) if (WINDOWS) - target_link_libraries( ll::libxml INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libxml2.lib Bcrypt.lib) -else() - target_link_libraries( ll::libxml INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libxml2.a) + target_link_libraries( ll::libxml INTERFACE Bcrypt.lib) endif() target_include_directories( ll::colladadom SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/collada ${LIBS_PREBUILT_DIR}/include/collada/1.4 ) -if (WINDOWS) - target_link_libraries(ll::colladadom INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libcollada14dom23-s.lib ll::libxml ll::minizip-ng ) -elseif (DARWIN) - target_link_libraries(ll::colladadom INTERFACE collada14dom ll::boost ll::libxml ll::minizip-ng) -elseif (LINUX) - target_link_libraries(ll::colladadom INTERFACE collada14dom ll::boost ll::libxml ll::minizip-ng) -endif() + +find_library(COLLADADOM_LIBRARY + NAMES + libcollada14dom23-s.lib + collada14dom + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::colladadom INTERFACE ${COLLADADOM_LIBRARY} ll::boost ll::libxml ll::minizip-ng) diff --git a/indra/cmake/LibVLCPlugin.cmake b/indra/cmake/LibVLCPlugin.cmake index 599ce028445..6361028c0c4 100644 --- a/indra/cmake/LibVLCPlugin.cmake +++ b/indra/cmake/LibVLCPlugin.cmake @@ -9,20 +9,16 @@ use_prebuilt_binary(vlc-bin) set(LIBVLCPLUGIN ON CACHE BOOL "LIBVLCPLUGIN support for the llplugin/llmedia test apps.") -if (WINDOWS) - target_link_libraries( ll::libvlc INTERFACE - libvlc.lib - libvlccore.lib - ) -elseif (DARWIN) - target_link_libraries( ll::libvlc INTERFACE - libvlc.dylib - libvlccore.dylib - ) -elseif (LINUX) - # Specify a full path to make sure we get a static link - target_link_libraries( ll::libvlc INTERFACE - ${LIBS_PREBUILT_DIR}/lib/libvlc.a - ${LIBS_PREBUILT_DIR}/lib/libvlccore.a - ) -endif (WINDOWS) +find_library(VLC_LIBRARY + NAMES + libvlc.lib + libvlc.dylib + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(VLCCORE_LIBRARY + NAMES + libvlccore.lib + libvlccore.dylib + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::libvlc INTERFACE ${VLC_LIBRARY} ${VLCCORE_LIBRARY}) diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake index 8451659c34d..900a64e2dd4 100644 --- a/indra/cmake/Linking.cmake +++ b/indra/cmake/Linking.cmake @@ -38,9 +38,10 @@ endif () # windows) and CMAKE_BUILD_TYPE on Makefile based generators (like linux). The reason for this is # that CMAKE_BUILD_TYPE is essentially meaningless at configuration time for IDE generators and # CMAKE_CFG_INTDIR is meaningless at build time for Makefile generators - -link_directories(${AUTOBUILD_INSTALL_DIR}/lib/$>) -link_directories(${AUTOBUILD_INSTALL_DIR}/lib/release) +if(NOT DARWIN) + link_directories(${AUTOBUILD_INSTALL_DIR}/lib/$>) + link_directories(${AUTOBUILD_INSTALL_DIR}/lib/release) +endif(NOT DARWIN) add_library( ll::oslibraries INTERFACE IMPORTED ) @@ -74,6 +75,8 @@ else() find_library(APPKIT_LIBRARY AppKit) find_library(COREAUDIO_LIBRARY CoreAudio) + find_library(COREGRAPHICS_LIBRARY CoreGraphics) + find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox) target_link_libraries( ll::oslibraries INTERFACE ${COCOA_LIBRARY} @@ -82,6 +85,8 @@ else() ${CARBON_LIBRARY} ${APPKIT_LIBRARY} ${COREAUDIO_LIBRARY} + ${AUDIOTOOLBOX_LIBRARY} + ${COREGRAPHICS_LIBRARY} ) endif() diff --git a/indra/cmake/Meshoptimizer.cmake b/indra/cmake/Meshoptimizer.cmake index fd144d2b97c..af1c51f032a 100644 --- a/indra/cmake/Meshoptimizer.cmake +++ b/indra/cmake/Meshoptimizer.cmake @@ -9,12 +9,12 @@ add_library( ll::meshoptimizer INTERFACE IMPORTED ) use_system_binary(meshoptimizer) use_prebuilt_binary(meshoptimizer) -if (WINDOWS) - target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.lib) -elseif (LINUX) - target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.o) -elseif (DARWIN) - target_link_libraries( ll::meshoptimizer INTERFACE libmeshoptimizer.a) -endif (WINDOWS) +find_library(MESHOPTIMIZER_LIBRARY + NAMES + meshoptimizer.lib + libmeshoptimizer.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) -target_include_directories( ll::meshoptimizer SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/meshoptimizer) +target_link_libraries(ll::meshoptimizer INTERFACE ${MESHOPTIMIZER_LIBRARY}) + +target_include_directories(ll::meshoptimizer SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/meshoptimizer) diff --git a/indra/cmake/NDOF.cmake b/indra/cmake/NDOF.cmake index b88fbccf2a1..a8f63f945b1 100644 --- a/indra/cmake/NDOF.cmake +++ b/indra/cmake/NDOF.cmake @@ -13,12 +13,15 @@ if (NDOF) use_prebuilt_binary(open-libndofdev) endif (WINDOWS OR DARWIN) - if (WINDOWS) - target_link_libraries( ll::ndof INTERFACE libndofdev) - elseif (DARWIN OR LINUX) - target_link_libraries( ll::ndof INTERFACE ndofdev) - endif (WINDOWS) - target_compile_definitions( ll::ndof INTERFACE LIB_NDOF=1) + find_library(NDOF_LIBRARY + NAMES + libndofdev + ndofdev + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + target_link_libraries(ll::ndof INTERFACE ${NDOF_LIBRARY}) + + target_compile_definitions(ll::ndof INTERFACE LIB_NDOF=1) endif (NDOF) diff --git a/indra/cmake/NGHTTP2.cmake b/indra/cmake/NGHTTP2.cmake index 7b2aa5971f5..e81204d7166 100644 --- a/indra/cmake/NGHTTP2.cmake +++ b/indra/cmake/NGHTTP2.cmake @@ -6,9 +6,12 @@ add_library( ll::nghttp2 INTERFACE IMPORTED ) use_system_binary(nghttp2) use_prebuilt_binary(nghttp2) -if (WINDOWS) - target_link_libraries( ll::nghttp2 INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/nghttp2.lib) -else () - target_link_libraries( ll::nghttp2 INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libnghttp2.a) -endif () + +find_library(NGHTTP2_LIBRARY + NAMES + nghttp2.lib + libnghttp2.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::nghttp2 INTERFACE ${NGHTTP2_LIBRARY}) target_include_directories( ll::nghttp2 SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/nghttp2) diff --git a/indra/cmake/OPENAL.cmake b/indra/cmake/OPENAL.cmake index 347dd02cd7d..ab1604aa22a 100644 --- a/indra/cmake/OPENAL.cmake +++ b/indra/cmake/OPENAL.cmake @@ -8,7 +8,7 @@ include_guard() # to have memory leaks, has no option to play music streams # It probably makes sense to to completely remove it -set(USE_OPENAL OFF CACHE BOOL "Enable OpenAL") +set(USE_OPENAL ON CACHE BOOL "Enable OpenAL") # ND: To streamline arguments passed, switch from OPENAL to USE_OPENAL # To not break all old build scripts convert old arguments but warn about it if(OPENAL) @@ -22,20 +22,21 @@ if (USE_OPENAL) target_compile_definitions( ll::openal INTERFACE LL_OPENAL=1) use_prebuilt_binary(openal) - if(WINDOWS) - target_link_libraries( ll::openal INTERFACE - OpenAL32 - alut - ) - elseif(LINUX) - target_link_libraries( ll::openal INTERFACE - openal - alut - ) - else() - target_link_libraries( ll::openal INTERFACE - openal - alut - ) - endif() + find_library(OPENAL_LIBRARY + NAMES + OpenAL32 + openal + libopenal.dylib + libopenal.so + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + find_library(ALUT_LIBRARY + NAMES + alut + libalut.dylib + libalut.so + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + target_link_libraries(ll::openal INTERFACE ${OPENAL_LIBRARY} ${ALUT_LIBRARY}) + endif () diff --git a/indra/cmake/OpenJPEG.cmake b/indra/cmake/OpenJPEG.cmake index c4aab2e9e53..95e71fd78e8 100644 --- a/indra/cmake/OpenJPEG.cmake +++ b/indra/cmake/OpenJPEG.cmake @@ -1,11 +1,22 @@ # -*- cmake -*- +include_guard() + include(Prebuilt) +include(Linking) -include_guard() add_library( ll::openjpeg INTERFACE IMPORTED ) use_system_binary(openjpeg) use_prebuilt_binary(openjpeg) -target_link_libraries(ll::openjpeg INTERFACE openjp2 ) -target_include_directories( ll::openjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/openjpeg) +find_library(OPENJPEG_LIBRARY + NAMES + openjp2 + openjp2.lib + libopenjp2.a + libopenjp2.so + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::openjpeg INTERFACE ${OPENJPEG_LIBRARY}) + +target_include_directories(ll::openjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/openjpeg) diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake index 67a84e14afd..9d33f2e0dec 100644 --- a/indra/cmake/OpenSSL.cmake +++ b/indra/cmake/OpenSSL.cmake @@ -7,12 +7,24 @@ add_library( ll::openssl INTERFACE IMPORTED ) use_system_binary(openssl) use_prebuilt_binary(openssl) + +find_library(SSL_LIBRARY + NAMES + libssl.lib + libssl.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(CRYPTO_LIBRARY + NAMES + libcrypto.lib + libcrypto.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::openssl INTERFACE ${SSL_LIBRARY} ${CRYPTO_LIBRARY}) + if (WINDOWS) - target_link_libraries(ll::openssl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libssl.lib ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto.lib Crypt32.lib) -elseif (LINUX) - target_link_libraries(ll::openssl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libssl.a ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto.a dl) -else() - target_link_libraries(ll::openssl INTERFACE ssl crypto) + target_link_libraries(ll::openssl INTERFACE Crypt32.lib) endif (WINDOWS) -target_include_directories( ll::openssl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) + +target_include_directories(ll::openssl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake index e5893e9a206..0c01e5ee78f 100644 --- a/indra/cmake/PNG.cmake +++ b/indra/cmake/PNG.cmake @@ -6,9 +6,12 @@ add_library( ll::libpng INTERFACE IMPORTED ) use_system_binary(libpng) use_prebuilt_binary(libpng) -if (WINDOWS) - target_link_libraries(ll::libpng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libpng16.lib) -else() - target_link_libraries(ll::libpng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libpng16.a) -endif() -target_include_directories( ll::libpng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/libpng16) + +find_library(LIBPNG_LIBRARY + NAMES + libpng16.lib + libpng16.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::libpng INTERFACE ${LIBPNG_LIBRARY}) +target_include_directories(ll::libpng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/libpng16) diff --git a/indra/cmake/PluginAPI.cmake b/indra/cmake/PluginAPI.cmake index 114415e514b..a2bf13db2c9 100644 --- a/indra/cmake/PluginAPI.cmake +++ b/indra/cmake/PluginAPI.cmake @@ -1,5 +1,7 @@ # -*- cmake -*- +include(OpenGL) + add_library( ll::pluginlibraries INTERFACE IMPORTED ) if (WINDOWS) @@ -13,4 +15,6 @@ if (WINDOWS) ) endif (WINDOWS) +target_link_libraries( ll::pluginlibraries INTERFACE OpenGL::GL) +target_include_directories( ll::pluginlibraries INTERFACE ${CMAKE_SOURCE_DIR}/llimage ${CMAKE_SOURCE_DIR}/llrender) diff --git a/indra/cmake/SSE2NEON.cmake b/indra/cmake/SSE2NEON.cmake new file mode 100644 index 00000000000..797f2af80e2 --- /dev/null +++ b/indra/cmake/SSE2NEON.cmake @@ -0,0 +1,12 @@ +# -*- cmake -*- + +include(Prebuilt) + +add_library(ll::sse2neon INTERFACE IMPORTED) + +if (DARWIN) + use_system_binary(sse2neon) + use_prebuilt_binary(sse2neon) + + target_include_directories( ll::sse2neon SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/sse2neon) +endif() diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index a7eac2711fe..cb09337d15e 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -15,6 +15,7 @@ endif() if (USE_TRACY) option(USE_TRACY_ON_DEMAND "Use on-demand Tracy profiling." ON) option(USE_TRACY_LOCAL_ONLY "Disallow remote Tracy profiling." OFF) + option(USE_TRACY_GPU "Use Tracy GPU profiling" OFF) use_system_binary(tracy) use_prebuilt_binary(tracy) @@ -31,9 +32,8 @@ if (USE_TRACY) target_compile_definitions(ll::tracy INTERFACE -DTRACY_NO_BROADCAST=1 -DTRACY_ONLY_LOCALHOST=1) endif () - # GHA runners don't always provide invariant TSC support, but always build with LL_TESTS enabled - if (DARWIN AND LL_TESTS) - target_compile_definitions(ll::tracy INTERFACE -DTRACY_TIMER_FALLBACK=1) + if (USE_TRACY_GPU AND NOT DARWIN) # Tracy OpenGL mode is incompatible with macOS/iOS + target_compile_definitions(ll::tracy INTERFACE -DLL_PROFILER_ENABLE_TRACY_OPENGL=1) endif () # See: indra/llcommon/llprofiler.h diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 5b3aeb8b7f8..22c2156bb88 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -144,52 +144,19 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(DARWIN 1) string(REGEX MATCH "-mmacosx-version-min=([^ ]+)" scratch "$ENV{LL_BUILD}") - set(CMAKE_OSX_DEPLOYMENT_TARGET "${CMAKE_MATCH_1}") + set(CMAKE_OSX_DEPLOYMENT_TARGET "${CMAKE_MATCH_1}" CACHE STRING "macOS Deploy Target" FORCE) message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET = '${CMAKE_OSX_DEPLOYMENT_TARGET}'") - string(REGEX MATCH "-stdlib=([^ ]+)" scratch "$ENV{LL_BUILD}") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "${CMAKE_MATCH_1}") - message(STATUS "CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY = '${CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY}'") - - string(REGEX MATCH " -g([^ ]*)" scratch "$ENV{LL_BUILD}") - set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "${CMAKE_MATCH_1}") - # -gdwarf-2 is passed in LL_BUILD according to 00-COMPILE-LINK-RUN.txt. - # However, when CMake 3.9.2 sees -gdwarf-2, it silently deletes the whole -g - # switch, producing no symbols at all! The same thing happens if we specify - # plain -g ourselves, i.e. CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT is - # the empty string. Specifying -gdwarf-with-dsym or just -gdwarf drives a - # different CMake behavior: it substitutes plain -g. As of 2017-09-19, - # viewer-build-variables/variables still passes -gdwarf-2, which is the - # no-symbols case. Set -gdwarf, triggering CMake to substitute plain -g -- - # at least that way we should get symbols, albeit mangled ones. It Would Be - # Nice if CMake's behavior could be predicted from a consistent mental - # model, instead of only observed experimentally. - string(REPLACE "dwarf-2" "dwarf" - CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT - "${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}") - message(STATUS "CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT = '${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}'") + # Use dwarf symbols for most libraries for compilation speed + set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf") string(REGEX MATCH "-O([^ ]*)" scratch "$ENV{LL_BUILD}") set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL "${CMAKE_MATCH_1}") message(STATUS "CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL = '${CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL}'") - # allow disabling this check by setting LL_SKIP_REQUIRE_SYSROOT either ON as cmake cache var or non-empty as environment var - set(LL_SKIP_REQUIRE_SYSROOT OFF CACHE BOOL "Skip requirement to set toolchain sysroot ahead of time. Not skipped by default for consistency, but skipping can be useful for selecting alternative xcode versions side by side") - if("$ENV{LL_SKIP_REQUIRE_SYSROOT}" STREQUAL "" AND NOT ${LL_SKIP_REQUIRE_SYSROOT}) - string(REGEX MATCHALL "[^ ]+" LL_BUILD_LIST "$ENV{LL_BUILD}") - list(FIND LL_BUILD_LIST "-iwithsysroot" sysroot_idx) - if ("${sysroot_idx}" LESS 0) - message(FATAL_ERROR "Environment variable LL_BUILD must contain '-iwithsysroot'") - endif () - math(EXPR sysroot_idx "${sysroot_idx} + 1") - list(GET LL_BUILD_LIST "${sysroot_idx}" CMAKE_OSX_SYSROOT) - endif() - message(STATUS "CMAKE_OSX_SYSROOT = '${CMAKE_OSX_SYSROOT}'") - - set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0") set(CMAKE_XCODE_ATTRIBUTE_GCC_STRICT_ALIASING NO) set(CMAKE_XCODE_ATTRIBUTE_GCC_FAST_MATH NO) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS ssse3) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS sse4.2) # we must hard code this to off for now. xcode's built in signing does not # handle embedded app bundles such as CEF and others. Any signing for local # development must be done after the build as we do in viewer_manifest.py for @@ -204,9 +171,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "") set(CMAKE_XCODE_ATTRIBUTE_DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING YES) set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION NO) - set(CMAKE_OSX_ARCHITECTURES "${ARCH}") - string(REPLACE "i686" "i386" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") - string(REPLACE "AMD64" "x86_64" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "macOS Build Arch" FORCE) endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # Default deploy grid diff --git a/indra/cmake/WebRTC.cmake b/indra/cmake/WebRTC.cmake index 230522a40af..7fefaa41522 100644 --- a/indra/cmake/WebRTC.cmake +++ b/indra/cmake/WebRTC.cmake @@ -1,32 +1,24 @@ # -*- cmake -*- +include_guard() + include(Linking) include(Prebuilt) -include_guard() - add_library( ll::webrtc INTERFACE IMPORTED ) target_include_directories( ll::webrtc SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/webrtc" "${LIBS_PREBUILT_DIR}/include/webrtc/third_party/abseil-cpp") use_prebuilt_binary(webrtc) -if (WINDOWS) - target_link_libraries( ll::webrtc INTERFACE webrtc.lib ) -elseif (DARWIN) - FIND_LIBRARY(COREAUDIO_LIBRARY CoreAudio) - FIND_LIBRARY(COREGRAPHICS_LIBRARY CoreGraphics) - FIND_LIBRARY(AUDIOTOOLBOX_LIBRARY AudioToolbox) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation) - FIND_LIBRARY(COCOA_LIBRARY Cocoa) +find_library(WEBRTC_LIBRARY + NAMES + webrtc + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries( ll::webrtc INTERFACE ${WEBRTC_LIBRARY} ) - target_link_libraries( ll::webrtc INTERFACE - libwebrtc.a - ${COREAUDIO_LIBRARY} - ${AUDIOTOOLBOX_LIBRARY} - ${COREGRAPHICS_LIBRARY} - ${COREFOUNDATION_LIBRARY} - ${COCOA_LIBRARY} - ) +if (DARWIN) + target_link_libraries( ll::webrtc INTERFACE ll::oslibraries ) elseif (LINUX) - target_link_libraries( ll::webrtc INTERFACE libwebrtc.a X11 ) -endif (WINDOWS) + target_link_libraries( ll::webrtc INTERFACE X11 ) +endif () diff --git a/indra/cmake/ZLIBNG.cmake b/indra/cmake/ZLIBNG.cmake index d7b920da26d..a6d67489e71 100644 --- a/indra/cmake/ZLIBNG.cmake +++ b/indra/cmake/ZLIBNG.cmake @@ -11,11 +11,14 @@ if(USE_CONAN ) endif() use_prebuilt_binary(zlib-ng) -if (WINDOWS) - target_link_libraries( ll::zlib-ng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/zlib.lib ) -else() - target_link_libraries( ll::zlib-ng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libz.a ) -endif (WINDOWS) + +find_library(ZLIBNG_LIBRARY + NAMES + zlib.lib + libz.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +target_link_libraries(ll::zlib-ng INTERFACE ${ZLIBNG_LIBRARY}) if( NOT LINUX ) target_include_directories( ll::zlib-ng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/zlib-ng) diff --git a/indra/cmake/websocketpp.cmake b/indra/cmake/websocketpp.cmake new file mode 100644 index 00000000000..726f0a5e0b4 --- /dev/null +++ b/indra/cmake/websocketpp.cmake @@ -0,0 +1,7 @@ +# -*- cmake -*- +include(Prebuilt) + +add_library( ll::websocketpp INTERFACE IMPORTED ) + +use_system_binary( websocketpp ) +use_prebuilt_binary(websocketpp) diff --git a/indra/cmake/xxHash.cmake b/indra/cmake/xxHash.cmake index a7c1cba62c9..e4f8517d9bf 100644 --- a/indra/cmake/xxHash.cmake +++ b/indra/cmake/xxHash.cmake @@ -1,8 +1,5 @@ # -*- cmake -*- -if (XXHASH_CMAKE_INCLUDED) - return() -endif (XXHASH_CMAKE_INCLUDED) -set (XXHASH_CMAKE_INCLUDED TRUE) +include_guard() include(Prebuilt) use_prebuilt_binary(xxhash) diff --git a/indra/doxygen/CMakeLists.txt b/indra/doxygen/CMakeLists.txt index 354ae7b6369..43ebf4ae263 100644 --- a/indra/doxygen/CMakeLists.txt +++ b/indra/doxygen/CMakeLists.txt @@ -1,13 +1,5 @@ # -*- cmake -*- -set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING - "The root project/makefile/solution name. Defaults to SecondLife.") -project(${ROOT_PROJECT_NAME}) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") - -include(Variables) - # add a target to generate API documentation with Doxygen find_package(Doxygen) if(DOXYGEN_FOUND) diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt deleted file mode 100644 index 8b137891791..00000000000 --- a/indra/edit-me-to-trigger-new-build.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/indra/integration_tests/CMakeLists.txt b/indra/integration_tests/CMakeLists.txt index ced2b3dbcfb..1d5f0772b5a 100644 --- a/indra/integration_tests/CMakeLists.txt +++ b/indra/integration_tests/CMakeLists.txt @@ -1,8 +1,3 @@ # -*- cmake -*- add_subdirectory(llui_libtest) -IF (LLIMAGE_LIBTEST) - MESSAGE(STATUS "Build llimage_libtest") - add_subdirectory(llimage_libtest) -ELSE (LLIMAGE_LIBTEST) - MESSAGE(STATUS "Skip llimage_libtest") -ENDIF (LLIMAGE_LIBTEST) +add_subdirectory(llimage_libtest) diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt index ee2890778b4..e6ff142626c 100644 --- a/indra/integration_tests/llimage_libtest/CMakeLists.txt +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -1,6 +1,7 @@ # -*- cmake -*- # Integration tests of the llimage library (JPEG2000, PNG, jpeg, etc... images reading and writing) +if (LL_TESTS) project (llimage_libtest) @@ -8,9 +9,7 @@ include(00-Common) include(LLCommon) include(LLImage) include(LLMath) -include(LLImageJ2COJ) include(LLKDU) -include(LLFileSystem) set(llimage_libtest_SOURCE_FILES llimage_libtest.cpp @@ -24,17 +23,9 @@ set(llimage_libtest_HEADER_FILES list(APPEND llimage_libtest_SOURCE_FILES ${llimage_libtest_HEADER_FILES}) add_executable(llimage_libtest - WIN32 - MACOSX_BUNDLE ${llimage_libtest_SOURCE_FILES} ) -set_target_properties(llimage_libtest - PROPERTIES - WIN32_EXECUTABLE - FALSE -) - # Libraries on which this application depends on # Sort by high-level to low-level target_link_libraries(llimage_libtest @@ -42,64 +33,9 @@ target_link_libraries(llimage_libtest llfilesystem llmath llimage - llkdu - llimagej2coj ) - -if (DARWIN) - # Path inside the app bundle where we'll need to copy libraries - set(LLIMAGE_LIBTEST_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/$,$,>/llimage_libtest.app/Contents/Resources - ) - # Create the Contents/Resources directory - add_custom_command( - TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - make_directory - ${LLIMAGE_LIBTEST_DESTINATION_DIR} - COMMENT "Creating Resources directory in app bundle." - ) -else (DARWIN) - set(LLIMAGE_LIBTEST_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ - ) -endif (DARWIN) - -get_target_property(BUILT_LLCOMMON llcommon LOCATION) -add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON} ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${BUILT_LLCOMMON} -) - -if (DARWIN) - # Copy the required libraries to the package app - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib - ) - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib - ) - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib - ) - foreach(expat ${EXPAT_COPY}) - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} - ) - endforeach(expat) -endif (DARWIN) - -if (WINDOWS) - # Check indra/test_apps/llplugintest/CMakeLists.txt for an example of what to copy over for Windows and how -endif (WINDOWS) # Ensure people working on the viewer don't break this library -# *NOTE: This could be removed, or only built by TeamCity, if the build -# and link times become too long. add_dependencies(viewer llimage_libtest) + +endif(LL_TESTS) diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 95102094aec..c45bd6fd01a 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -43,6 +43,8 @@ #include "v4coloru.h" #include "llsdserialize.h" #include "llcleanup.h" +#include "lltrace.h" +#include "llfasttimer.h" // system libraries #include @@ -573,10 +575,10 @@ int main(int argc, char** argv) // Create the logging thread if required - if (LLFastTimer::sMetricLog) + if (LLTrace::BlockTimer::sMetricLog) { - LLFastTimer::sLogLock = new LLMutex(NULL); - fast_timer_log_thread = new LogThread(LLFastTimer::sLogName); + LLTrace::BlockTimer::setLogLock(new LLMutex()); + fast_timer_log_thread = new LogThread(LLTrace::BlockTimer::sLogName); fast_timer_log_thread->start(); } @@ -618,9 +620,9 @@ int main(int argc, char** argv) // Output perf data if requested by user if (analyze_performance) { - std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; - std::string current_name = LLFastTimer::sLogName + ".slp"; - std::string report_name = LLFastTimer::sLogName + "_report.csv"; + std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp"; + std::string current_name = LLTrace::BlockTimer::sLogName + ".slp"; + std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv"; std::cout << "Analyzing performance, check report in : " << report_name << std::endl; @@ -628,9 +630,9 @@ int main(int argc, char** argv) } // Stop the perf gathering system if needed - if (LLFastTimer::sMetricLog) + if (LLTrace::BlockTimer::sMetricLog) { - LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName); + LLMetricPerformanceTesterBasic::deleteTester(LLTrace::BlockTimer::sLogName); sAllDone = true; } diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp index 83e7fad92fd..d115dc309d2 100644 --- a/indra/llaudio/llvorbisencode.cpp +++ b/indra/llaudio/llvorbisencode.cpp @@ -34,38 +34,6 @@ #include "llmath.h" #include "llapr.h" -//#if LL_DARWIN -// MBW -- XXX -- Getting rid of SecondLifeVorbis for now -#if 0 -#include "VorbisFramework.h" - -#define vorbis_analysis mac_vorbis_analysis -#define vorbis_analysis_headerout mac_vorbis_analysis_headerout -#define vorbis_analysis_init mac_vorbis_analysis_init -#define vorbis_encode_ctl mac_vorbis_encode_ctl -#define vorbis_encode_setup_init mac_vorbis_encode_setup_init -#define vorbis_encode_setup_managed mac_vorbis_encode_setup_managed - -#define vorbis_info_init mac_vorbis_info_init -#define vorbis_info_clear mac_vorbis_info_clear -#define vorbis_comment_init mac_vorbis_comment_init -#define vorbis_comment_clear mac_vorbis_comment_clear -#define vorbis_block_init mac_vorbis_block_init -#define vorbis_block_clear mac_vorbis_block_clear -#define vorbis_dsp_clear mac_vorbis_dsp_clear -#define vorbis_analysis_buffer mac_vorbis_analysis_buffer -#define vorbis_analysis_wrote mac_vorbis_analysis_wrote -#define vorbis_analysis_blockout mac_vorbis_analysis_blockout - -#define ogg_stream_packetin mac_ogg_stream_packetin -#define ogg_stream_init mac_ogg_stream_init -#define ogg_stream_flush mac_ogg_stream_flush -#define ogg_stream_pageout mac_ogg_stream_pageout -#define ogg_page_eos mac_ogg_page_eos -#define ogg_stream_clear mac_ogg_stream_clear - -#endif - S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& error_msg) { U16 num_channels = 0; diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index a504e71340b..daa1def7263 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -11,7 +11,7 @@ include(LLSharedLibs) include(Copy3rdPartyLibs) include(ZLIBNG) include(Tracy) - +include(SSE2NEON) set(llcommon_SOURCE_FILES apply.cpp @@ -277,6 +277,7 @@ target_link_libraries( ll::boost ll::oslibraries ll::tracy + ll::sse2neon ) target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) @@ -313,7 +314,7 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llmainthreadtask "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llpounceable "" "${test_libs}") - LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}") + #LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}") RIDER: Test is a known failure. Disabling for the moment. LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llprocinfo "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}") diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h index e9c96edce39..2c900c02a70 100644 --- a/indra/llcommon/fsyspath.h +++ b/indra/llcommon/fsyspath.h @@ -12,7 +12,10 @@ #if ! defined(LL_FSYSPATH_H) #define LL_FSYSPATH_H +#include #include +#include +#include // While std::filesystem::path can be directly constructed from std::string on // both Posix and Windows, that's not what we want on Windows. Per @@ -33,37 +36,43 @@ // char"), the "native narrow encoding" isn't UTF-8, so file paths containing // non-ASCII characters get mangled. // -// Once we're building with C++20, we could pass a UTF-8 std::string through a -// vector to engage std::filesystem::path's own UTF-8 conversion. But -// sigh, as of 2024-04-03 we're not yet there. -// -// Anyway, encapsulating the important UTF-8 conversions in our own subclass -// allows us to migrate forward to C++20 conventions without changing -// referencing code. +// Encapsulating the important UTF-8 conversions in our own subclass allows us +// to migrate forward to C++20 conventions without changing referencing code. class fsyspath: public std::filesystem::path { using super = std::filesystem::path; + // In C++20 (__cpp_lib_char8_t), std::filesystem::u8path() is deprecated. + // std::filesystem::path(iter, iter) performs UTF-8 conversions when the + // value_type of the iterators is char8_t. While we could copy into a + // temporary std::u8string and from there into std::filesystem::path, to + // minimize string copying we'll define a transform_iterator that accepts + // a std::string_view::iterator and dereferences to char8_t. + struct u8ify + { + char8_t operator()(char c) const { return char8_t(c); } + }; + using u8iter = boost::transform_iterator; + public: // default fsyspath() {} - // construct from UTF-8 encoded std::string - fsyspath(const std::string& path): super(std::filesystem::u8path(path)) {} - // construct from UTF-8 encoded const char* - fsyspath(const char* path): super(std::filesystem::u8path(path)) {} + // construct from UTF-8 encoded string + fsyspath(const std::string& path): fsyspath(std::string_view(path)) {} + fsyspath(const char* path): fsyspath(std::string_view(path)) {} + fsyspath(std::string_view path): + super(u8iter(path.begin(), u8ify()), u8iter(path.end(), u8ify())) + {} // construct from existing path fsyspath(const super& path): super(path) {} - fsyspath& operator=(const super& p) { super::operator=(p); return *this; } - fsyspath& operator=(const std::string& p) - { - super::operator=(std::filesystem::u8path(p)); - return *this; - } - fsyspath& operator=(const char* p) + fsyspath& operator=(const super& p) { super::operator=(p); return *this; } + fsyspath& operator=(const std::string& p) { return (*this) = std::string_view(p); } + fsyspath& operator=(const char* p) { return (*this) = std::string_view(p); } + fsyspath& operator=(std::string_view p) { - super::operator=(std::filesystem::u8path(p)); + assign(u8iter(p.begin(), u8ify()), u8iter(p.end(), u8ify())); return *this; } diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index a918caa2e83..a41af153fe7 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -28,12 +28,6 @@ #define LL_LINDEN_COMMON_H #include "llprofiler.h" -#if TRACY_ENABLE && !defined(LL_PROFILER_ENABLE_TRACY_OPENGL) // hooks for memory profiling -void *tracy_aligned_malloc(size_t size, size_t alignment); -void tracy_aligned_free(void *memblock); -#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y)) -#define _aligned_free(X) tracy_aligned_free((X)) -#endif // *NOTE: Please keep includes here to a minimum! // diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 08a43983d32..c532620daa1 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -229,7 +229,7 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv) if(wargv[ii][1] == '-') ++offset; #if LL_WINDOWS - name.assign(utf16str_to_utf8str(&wargv[ii][offset])); + name.assign(ll_convert_wide_to_string(&wargv[ii][offset])); #else name.assign(wstring_to_utf8str(&wargv[ii][offset])); #endif @@ -253,7 +253,7 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv) ++ii; #if LL_WINDOWS - value.assign(utf16str_to_utf8str((wargv[ii]))); + value.assign(ll_convert_wide_to_string((wargv[ii]))); #else value.assign(wstring_to_utf8str((wargv[ii]))); #endif diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 84b35749ccd..7a22eaf2032 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -33,23 +33,23 @@ #include "lltracethreadrecorder.h" #include "llcleanup.h" -thread_local bool gProfilerEnabled = false; - -#if (TRACY_ENABLE) +#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY && TRACY_ENABLE // Override new/delete for tracy memory profiling void* ll_tracy_new(size_t size) { - void* ptr; - if (gProfilerEnabled) - { - //LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; - ptr = (malloc)(size); - } - else + void* ptr = (malloc)(size); + if (!ptr) { - ptr = (malloc)(size); + throw std::bad_alloc(); } + LL_PROFILE_ALLOC(ptr, size); + return ptr; +} + +void* ll_tracy_aligned_new(size_t size, size_t alignment) +{ + void* ptr = ll_aligned_malloc_fallback(size, alignment); if (!ptr) { throw std::bad_alloc(); @@ -58,6 +58,18 @@ void* ll_tracy_new(size_t size) return ptr; } +void ll_tracy_delete(void* ptr) +{ + LL_PROFILE_FREE(ptr); + (free)(ptr); +} + +void ll_tracy_aligned_delete(void* ptr) +{ + LL_PROFILE_FREE(ptr); + ll_aligned_free_fallback(ptr); +} + void* operator new(size_t size) { return ll_tracy_new(size); @@ -68,18 +80,14 @@ void* operator new[](std::size_t count) return ll_tracy_new(count); } -void ll_tracy_delete(void* ptr) +void* operator new(size_t size, std::align_val_t align) { - LL_PROFILE_FREE(ptr); - if (gProfilerEnabled) - { - //LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; - (free)(ptr); - } - else - { - (free)(ptr); - } + return ll_tracy_aligned_new(size, (size_t)align); +} + +void* operator new[](std::size_t count, std::align_val_t align) +{ + return ll_tracy_aligned_new(count, (size_t)align); } void operator delete(void *ptr) noexcept @@ -92,27 +100,17 @@ void operator delete[](void* ptr) noexcept ll_tracy_delete(ptr); } -// C-style malloc/free can't be so easily overridden, so we define tracy versions and use -// a pre-processor #define in linden_common.h to redirect to them. The parens around the native -// functions below prevents recursive substitution by the preprocessor. -// -// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at -// you, Havok), so we'll only capture the aligned version. - -void *tracy_aligned_malloc(size_t size, size_t alignment) +void operator delete(void *ptr, std::align_val_t align) noexcept { - auto ptr = ll_aligned_malloc_fallback(size, alignment); - if (ptr) LL_PROFILE_ALLOC(ptr, size); - return ptr; + ll_tracy_aligned_delete(ptr); } -void tracy_aligned_free(void *memblock) +void operator delete[](void* ptr, std::align_val_t align) noexcept { - LL_PROFILE_FREE(memblock); - ll_aligned_free_fallback(memblock); + ll_tracy_aligned_delete(ptr); } -#endif +#endif // TRACY_ENABLE && !LL_PROFILER_ENABLE_TRACY_OPENGL //static bool LLCommon::sAprInitialized = false; diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index d8340989948..3411e9c6bb5 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -79,7 +79,7 @@ namespace { // if (s.size()) { - OutputDebugString(utf8str_to_utf16str(s).c_str()); + OutputDebugString(ll_convert(s).c_str()); OutputDebugString(TEXT("\n")); } } diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 722743f4538..1c5fe9d2f53 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -64,7 +64,7 @@ bool BlockTimer::sLog = false; std::string BlockTimer::sLogName = ""; bool BlockTimer::sMetricLog = false; -#if LL_LINUX +#if LL_LINUX || (LL_DARWIN && LL_ARM64) U64 BlockTimer::sClockResolution = 1000000000; // Nanosecond resolution #else U64 BlockTimer::sClockResolution = 1000000; // Microsecond resolution diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 09fcf8a1afe..271dade0979 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -30,9 +30,14 @@ #include "llinstancetracker.h" #include "lltrace.h" #include "lltreeiterators.h" +#include "llprocessor.h" +#if LL_X86 || LL_X86_64 #if LL_WINDOWS #include +#else +#include +#endif #endif #define LL_FAST_TIMER_ON 1 @@ -68,35 +73,10 @@ class BlockTimer // // Windows implementation of CPU clock // - - // - // NOTE: put back in when we aren't using platform sdk anymore - // - // because MS has different signatures for these functions in winnt.h - // need to rename them to avoid conflicts - //#define _interlockedbittestandset _renamed_interlockedbittestandset - //#define _interlockedbittestandreset _renamed_interlockedbittestandreset - //#include - //#undef _interlockedbittestandset - //#undef _interlockedbittestandreset - - //inline U32 getCPUClockCount32() - //{ - // U64 time_stamp = __rdtsc(); - // return (U32)(time_stamp >> 8); - //} - // - //// return full timer value, *not* shifted by 8 bits - //inline U64 getCPUClockCount64() - //{ - // return __rdtsc(); - //} - - +#if LL_FASTTIMER_USE_RDTSC // shift off lower 8 bits for lower resolution but longer term timing // on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing -#if LL_FASTTIMER_USE_RDTSC static U32 getCPUClockCount32() { unsigned __int64 val = __rdtsc(); @@ -159,23 +139,37 @@ class BlockTimer #endif // (LL_LINUX) && !(defined(__i386__) || defined(__amd64__)) -#if (LL_LINUX || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) +#if LL_DARWIN && LL_ARM64 + // + // Mac implementation of CPU clock - non-x86. + // + static U64 getCPUClockCount64() + { + return clock_gettime_nsec_np(CLOCK_UPTIME_RAW); + } + + static U32 getCPUClockCount32() + { + return (U32)(getCPUClockCount64() >> 8); + } +#endif // LL_DARWIN && LL_ARM64 + +#if (LL_LINUX || LL_DARWIN) && (LL_X86 || LL_X86_64) // // Mac+Linux FAST x86 implementation of CPU clock + // +#if LL_FASTTIMER_USE_RDTSC static U32 getCPUClockCount32() { - U32 low(0),high(0); - __asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) ); - return (low>>8) | (high<<24); + U64 time_stamp = __rdtsc() >> 8U; + return static_cast(time_stamp); } static U64 getCPUClockCount64() { - U32 low(0),high(0); - __asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) ); - return (U64)low | ( ((U64)high) << 32); + return static_cast(__rdtsc()); } - +#endif #endif static BlockTimerStatHandle& getRootTimeBlock(); diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index d0bc8f7652d..53659ac13ff 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -178,8 +178,7 @@ int LLFile::mkdir(const std::string& dirname, int perms) { #if LL_WINDOWS // permissions are ignored on Windows - std::string utf8dirname = dirname; - llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname); + std::wstring utf16dirname = ll_convert(dirname); int rc = _wmkdir(utf16dirname.c_str()); #else int rc = ::mkdir(dirname.c_str(), (mode_t)perms); @@ -201,8 +200,7 @@ int LLFile::rmdir(const std::string& dirname) { #if LL_WINDOWS // permissions are ignored on Windows - std::string utf8dirname = dirname; - llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname); + std::wstring utf16dirname = ll_convert(dirname); int rc = _wrmdir(utf16dirname.c_str()); #else int rc = ::rmdir(dirname.c_str()); @@ -214,10 +212,8 @@ int LLFile::rmdir(const std::string& dirname) LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawfinder: ignore */ { #if LL_WINDOWS - std::string utf8filename = filename; - std::string utf8mode = std::string(mode); - llutf16string utf16filename = utf8str_to_utf16str(utf8filename); - llutf16string utf16mode = utf8str_to_utf16str(utf8mode); + std::wstring utf16filename = ll_convert(filename); + std::wstring utf16mode = ll_convert(std::string(mode)); return _wfopen(utf16filename.c_str(),utf16mode.c_str()); #else return ::fopen(filename.c_str(),mode); /* Flawfinder: ignore */ @@ -227,10 +223,8 @@ LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawf LLFILE* LLFile::_fsopen(const std::string& filename, const char* mode, int sharingFlag) { #if LL_WINDOWS - std::string utf8filename = filename; - std::string utf8mode = std::string(mode); - llutf16string utf16filename = utf8str_to_utf16str(utf8filename); - llutf16string utf16mode = utf8str_to_utf16str(utf8mode); + std::wstring utf16filename = ll_convert(filename); + std::wstring utf16mode = ll_convert(std::string(mode)); return _wfsopen(utf16filename.c_str(),utf16mode.c_str(),sharingFlag); #else llassert(0);//No corresponding function on non-windows @@ -270,8 +264,7 @@ std::string LLFile::getContents(const std::string& filename) int LLFile::remove(const std::string& filename, int supress_error) { #if LL_WINDOWS - std::string utf8filename = filename; - llutf16string utf16filename = utf8str_to_utf16str(utf8filename); + std::wstring utf16filename = ll_convert(filename); int rc = _wremove(utf16filename.c_str()); #else int rc = ::remove(filename.c_str()); @@ -282,10 +275,8 @@ int LLFile::remove(const std::string& filename, int supress_error) int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error) { #if LL_WINDOWS - std::string utf8filename = filename; - std::string utf8newname = newname; - llutf16string utf16filename = utf8str_to_utf16str(utf8filename); - llutf16string utf16newname = utf8str_to_utf16str(utf8newname); + std::wstring utf16filename = ll_convert(filename); + std::wstring utf16newname = ll_convert(newname); int rc = _wrename(utf16filename.c_str(),utf16newname.c_str()); #else int rc = ::rename(filename.c_str(),newname.c_str()); @@ -327,8 +318,7 @@ bool LLFile::copy(const std::string& from, const std::string& to) int LLFile::stat(const std::string& filename, llstat* filestatus) { #if LL_WINDOWS - std::string utf8filename = filename; - llutf16string utf16filename = utf8str_to_utf16str(utf8filename); + std::wstring utf16filename = ll_convert(filename); int rc = _wstat(utf16filename.c_str(),filestatus); #else int rc = ::stat(filename.c_str(),filestatus); @@ -453,14 +443,14 @@ llifstream::llifstream() {} // explicit llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode): - std::ifstream(utf8str_to_utf16str( _Filename ).c_str(), + std::ifstream(ll_convert( _Filename ).c_str(), _Mode | ios_base::in) { } void llifstream::open(const std::string& _Filename, ios_base::openmode _Mode) { - std::ifstream::open(utf8str_to_utf16str(_Filename).c_str(), + std::ifstream::open(ll_convert(_Filename).c_str(), _Mode | ios_base::in); } @@ -472,14 +462,14 @@ llofstream::llofstream() {} // explicit llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode): - std::ofstream(utf8str_to_utf16str( _Filename ).c_str(), + std::ofstream(ll_convert( _Filename ).c_str(), _Mode | ios_base::out) { } void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode) { - std::ofstream::open(utf8str_to_utf16str( _Filename ).c_str(), + std::ofstream::open(ll_convert( _Filename ).c_str(), _Mode | ios_base::out); } diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index 662a2511cdc..ada6b9519e5 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -188,6 +188,17 @@ class LLLeapImpl: public LLLeap << childout.peek(0, peeklen) << "..." << LL_ENDL; } + // Handle any remaining stderr data (partial lines) the same way as we do + // for stdout: log it. + LLProcess::ReadPipe& childerr(mChild->getReadPipe(LLProcess::STDERR)); + if (childerr.size()) + { + LLProcess::ReadPipe::size_type + peeklen((std::min)(LLProcess::ReadPipe::size_type(50), childerr.size())); + LL_WARNS("LLLeap") << "Final stderr " << childerr.size() << " bytes: " + << childerr.peek(0, peeklen) << "..." << LL_ENDL; + } + // Kill this instance. MUST BE LAST before return! delete this; return false; diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index e999b8f597d..c8ca586e7fc 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -255,6 +255,11 @@ void LLMD5::raw_digest(unsigned char* s) const memcpy(s, digest, 16); /* Flawfinder: ignore */ } +#if LL_DARWIN +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + void LLMD5::hex_digest(char* s) const { if (!finalized) @@ -273,6 +278,10 @@ void LLMD5::hex_digest(char* s) const s[32] = '\0'; } +#if LL_DARWIN +#pragma clang diagnostic pop +#endif + std::ostream& operator<<(std::ostream& stream, const LLMD5& context) { char s[33]; /* Flawfinder: ignore */ diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index b616edfde71..adc556d180f 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -71,7 +71,11 @@ LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); #define ll_assert_aligned(ptr,alignment) #endif +#if LL_ARM64 +#include "sse2neon.h" +#else #include +#endif template T* LL_NEXT_ALIGNED_ADDRESS(T* address) { @@ -231,8 +235,6 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; #if defined(LL_WINDOWS) void* ret = _aligned_malloc(size, 32); -#elif defined(LL_DARWIN) - void* ret = ll_aligned_malloc_fallback( size, 32 ); #else void *ret; if (0 != posix_memalign(&ret, 32, size)) @@ -248,8 +250,31 @@ inline void ll_aligned_free_32(void *p) LL_PROFILE_FREE(p); #if defined(LL_WINDOWS) _aligned_free(p); -#elif defined(LL_DARWIN) - ll_aligned_free_fallback( p ); +#else + free(p); // posix_memalign() is compatible with heap deallocator +#endif +} + +inline void* ll_aligned_malloc_64(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; +#if defined(LL_WINDOWS) + void* ret = _aligned_malloc(size, 64); +#else + void *ret; + if (0 != posix_memalign(&ret, 64, size)) + return nullptr; +#endif + LL_PROFILE_ALLOC(ret, size); + return ret; +} + +inline void ll_aligned_free_64(void *p) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + LL_PROFILE_FREE(p); +#if defined(LL_WINDOWS) + _aligned_free(p); #else free(p); // posix_memalign() is compatible with heap deallocator #endif @@ -261,19 +286,23 @@ LL_FORCE_INLINE void* ll_aligned_malloc(size_t size) { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; void* ret; - if (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0) + if constexpr (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0) { ret = malloc(size); LL_PROFILE_ALLOC(ret, size); } - else if (ALIGNMENT == 16) + else if constexpr (ALIGNMENT == 16) { ret = ll_aligned_malloc_16(size); } - else if (ALIGNMENT == 32) + else if constexpr (ALIGNMENT == 32) { ret = ll_aligned_malloc_32(size); } + else if constexpr (ALIGNMENT == 64) + { + ret = ll_aligned_malloc_64(size); + } else { ret = ll_aligned_malloc_fallback(size, ALIGNMENT); @@ -285,16 +314,20 @@ template LL_FORCE_INLINE void ll_aligned_free(void* ptr) { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; - if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) + if constexpr (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { LL_PROFILE_FREE(ptr); free(ptr); } - else if (ALIGNMENT == 16) + else if constexpr (ALIGNMENT == 16) { ll_aligned_free_16(ptr); } - else if (ALIGNMENT == 32) + else if constexpr (ALIGNMENT == 32) + { + return ll_aligned_free_32(ptr); + } + else if constexpr (ALIGNMENT == 64) { return ll_aligned_free_32(ptr); } @@ -310,6 +343,9 @@ LL_FORCE_INLINE void ll_aligned_free(void* ptr) inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes) { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; +#if defined(LL_ARM64) + memcpy(dst, src, bytes); +#else assert(src != NULL); assert(dst != NULL); assert(bytes > 0); @@ -375,6 +411,7 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __ dst += 16; src += 16; } +#endif } #ifndef __DEBUG_PRIVATE_MEM__ diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index b499a9ce10e..b2a97345487 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -76,6 +76,23 @@ #endif #endif +// Set up CPU architecture defines +#if LL_MSVC && defined(_M_ARM64) +# define LL_ARM64 1 +#elif LL_GNUC && (defined(__arm64__) || defined(__aarch64__)) +# define LL_ARM64 1 +#elif LL_MSVC && _M_X64 +# define LL_X86_64 1 +# define LL_X86 1 +#elif LL_MSVC && _M_IX86 +# define LL_X86 1 +#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) +# define LL_X86_64 1 +# define LL_X86 1 +#elif LL_GNUC && ( defined(__i386__) ) +# define LL_X86 1 +#endif + // Deal with minor differences on Unixy OSes. #if LL_DARWIN || LL_LINUX // Different name, same functionality. @@ -118,11 +135,8 @@ #if LL_WINDOWS #define LL_DLLEXPORT __declspec(dllexport) #define LL_DLLIMPORT __declspec(dllimport) -#elif LL_LINUX -#define LL_DLLEXPORT __attribute__ ((visibility("default"))) -#define LL_DLLIMPORT #else -#define LL_DLLEXPORT +#define LL_DLLEXPORT __attribute__ ((visibility("default"))) #define LL_DLLIMPORT #endif // LL_WINDOWS @@ -167,7 +181,7 @@ #define LL_TO_STRING_HELPER(x) #x #define LL_TO_STRING(x) LL_TO_STRING_HELPER(x) -#define LL_TO_WSTRING_HELPER(x) L#x +#define LL_TO_WSTRING_HELPER(x) L## #x #define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x) #define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg #define LL_GLUE_IMPL(x, y) x##y @@ -187,4 +201,16 @@ #define LL_PRETTY_FUNCTION __PRETTY_FUNCTION__ #endif +#if LL_ARM64 +#define GLM_FORCE_NEON 1 +#else +#define GLM_FORCE_SSE2 1 +#endif + +#if LL_ARM64 +#define KDU_NEON_INTRINSICS 1 +#else +#define KDU_X86_INTRINSICS 1 +#endif + #endif // not LL_LINDEN_PREPROCESSOR_H diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 2e94651083b..718f4713213 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -628,6 +628,8 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl #elif LL_DARWIN +#include +#include #include #include @@ -638,25 +640,21 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl { getCPUIDInfo(); uint64_t frequency = getSysctlInt64("hw.cpufrequency"); - if (!frequency) + if (frequency == 0) // fallback to clockrate and tbfrequency { - auto tbfrequency = getSysctlInt64("hw.tbfrequency"); - struct clockinfo clockrate; - auto clockrate_len = sizeof(clockrate); - if (!sysctlbyname("kern.clockrate", &clockrate, &clockrate_len, NULL, 0)) - frequency = tbfrequency * clockrate.hz; + frequency = getSysctlClockrate() * getSysctlInt64("hw.tbfrequency"); } setInfo(eFrequency, (F64)frequency / (F64)1000000); } - virtual ~LLProcessorInfoDarwinImpl() {} + virtual ~LLProcessorInfoDarwinImpl() = default; private: int getSysctlInt(const char* name) { int result = 0; size_t len = sizeof(int); - int error = sysctlbyname(name, (void*)&result, &len, NULL, 0); + int error = sysctlbyname(name, (void*)&result, &len, nullptr, 0); return error == -1 ? 0 : result; } @@ -664,7 +662,7 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl { uint64_t value = 0; size_t size = sizeof(value); - int result = sysctlbyname(name, (void*)&value, &size, NULL, 0); + int result = sysctlbyname(name, (void*)&value, &size, nullptr, 0); if ( result == 0 ) { if ( size == sizeof( uint64_t ) ) @@ -684,6 +682,14 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl return result == -1 ? 0 : value; } + uint64_t getSysctlClockrate() + { + struct clockinfo clockrate{}; + size_t size = sizeof(clockrate); + int error = sysctlbyname("kern.clockrate", &clockrate, &size, nullptr, 0); + return error == -1 ? 0 : clockrate.hz; + } + void getCPUIDInfo() { size_t len = 0; diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index f8ccf686c87..b955f7f55cf 100644 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -28,20 +28,7 @@ #ifndef LLPROCESSOR_H #define LLPROCESSOR_H #include "llunits.h" - -#if LL_MSVC && _M_X64 -# define LL_X86_64 1 -# define LL_X86 1 -#elif LL_MSVC && _M_IX86 -# define LL_X86 1 -#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) -# define LL_X86_64 1 -# define LL_X86 1 -#elif LL_GNUC && ( defined(__i386__) ) -# define LL_X86 1 -#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) ) -# define LL_PPC 1 -#endif +#include "llpreprocessor.h" class LLProcessorInfoImpl; diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index f6a4d247471..5fb32d62804 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -74,23 +74,18 @@ #define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER #endif -extern thread_local bool gProfilerEnabled; - #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #include "tracy/Tracy.hpp" - // Enable OpenGL profiling - #define LL_PROFILER_ENABLE_TRACY_OPENGL 0 - // Enable RenderDoc labeling - #define LL_PROFILER_ENABLE_RENDER_DOC 0 + //#define LL_PROFILER_ENABLE_RENDER_DOC 0 #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY #define LL_PROFILER_FRAME_END FrameMark - #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true; + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); #define LL_RECORD_BLOCK_TIME(name) ZoneScoped // Want descriptive names; was: ZoneNamedN( ___tracy_scoped_zone, #name, true ); #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB @@ -133,7 +128,7 @@ extern thread_local bool gProfilerEnabled; #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define LL_PROFILER_FRAME_END FrameMark - #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true; + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN(___tracy_scoped_zone, #name, true); const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB @@ -158,23 +153,20 @@ extern thread_local bool gProfilerEnabled; #endif // LL_PROFILER #if LL_PROFILER_ENABLE_TRACY_OPENGL -#define LL_PROFILE_GPU_ZONE(name) TracyGpuZone(name) -#define LL_PROFILE_GPU_ZONEC(name,color) TracyGpuZoneC(name,color) +#define LL_PROFILE_GPU_ZONE(name) TracyGpuZone(name) +#define LL_PROFILE_GPU_ZONEC(name,color) TracyGpuZoneC(name,color) #define LL_PROFILER_GPU_COLLECT TracyGpuCollect #define LL_PROFILER_GPU_CONTEXT TracyGpuContext - -// disable memory tracking (incompatible with GPU tracing -#define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size); -#define LL_PROFILE_FREE(ptr) (void)(ptr); +#define LL_PROFILER_GPU_CONTEXT_NAMED TracyGpuContextName #else -#define LL_PROFILE_GPU_ZONE(name) (void)name; -#define LL_PROFILE_GPU_ZONEC(name,color) (void)name;(void)color; +#define LL_PROFILE_GPU_ZONE(name) (void)name; +#define LL_PROFILE_GPU_ZONEC(name,color) (void)name;(void)color; #define LL_PROFILER_GPU_COLLECT #define LL_PROFILER_GPU_CONTEXT +#define LL_PROFILER_GPU_CONTEXT_NAMED(name) (void)name; +#endif // LL_PROFILER_ENABLE_TRACY_OPENGL -#define LL_LABEL_OBJECT_GL(type, name, length, label) - -#if !LL_DARWIN && LL_PROFILER_CONFIGURATION > 1 +#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY #define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size) #define LL_PROFILE_FREE(ptr) TracyFree(ptr) #else @@ -182,8 +174,6 @@ extern thread_local bool gProfilerEnabled; #define LL_PROFILE_FREE(ptr) (void)(ptr); #endif -#endif - #if LL_PROFILER_ENABLE_RENDER_DOC #define LL_LABEL_OBJECT_GL(type, name, length, label) glObjectLabel(type, name, length, label) #else diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 7d41c42ba7f..0088eeec67d 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef LL_LINUX // For strcmp @@ -709,5 +710,208 @@ struct ll_template_cast_impl \ } \ } +//----------------------------------------------- +namespace LL +{ + /** + * @brief A range adapter that provides filtered iteration over a container. + * + * filter_range creates a filtered view of an iterator range using a predicate function. + * Only elements that satisfy the predicate will be accessible when iterating through + * the range. This is useful for processing subsets of containers without copying data. + * + * The class uses boost::filter_iterator internally to provide the filtering functionality. + * + * @tparam Predicate A callable object (function, functor, lambda) that takes an element + * from the iterator range and returns true if the element should be + * included in the filtered range. + * @tparam Iterator The iterator type for the underlying container/range. + * + * Example usage: + * @code + * std::vector numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * + * // Create a predicate to filter even numbers + * auto is_even = [](int n) { return n % 2 == 0; }; + * + * // Create filtered range using make_filter helper + * auto even_range = LL::make_filter(is_even, numbers.begin(), numbers.end()); + * + * // Iterate through only even numbers + * for (auto value : even_range) { + * std::cout << value << " "; // Prints: 2 4 6 8 10 + * } + * + * // Or manually construct the filter_range + * LL::filter_range::iterator> + * manual_range(is_even, numbers.begin(), numbers.end()); + * @endcode + * + * @note This class provides a lightweight view over the original data. + * No copying of elements occurs, making it efficient for large containers. + * @note The predicate is applied during iteration, so complex predicates may + * impact performance for frequently-accessed ranges. + * @note The underlying container must remain valid for the lifetime of the filter_range. + * + * @see make_filter() for a convenient factory function + * @see boost::filter_iterator for the underlying implementation details + */ + template + class filter_range + { + public: + /// The filtered iterator type - combines predicate with base iterator + using filter_iter = boost::filter_iterator; + + /// Value type of the filtered elements + using value_type = typename std::iterator_traits::value_type; + + /// Iterator type for range-based for loops and STL algorithms + using iterator = filter_iter; + using const_iterator = filter_iter; + + /** + * @brief Constructs a filter_range with the given predicate and iterator range. + * + * @param pred The predicate function/functor to filter elements. + * Must be callable with signature: bool(const value_type&) + * @param begin Iterator to the beginning of the range to filter + * @param end Iterator to the end of the range to filter + * + * @pre begin and end must form a valid iterator range + * @pre pred must be a valid callable that can be invoked with elements from [begin, end) + */ + filter_range(Predicate pred, Iterator begin, Iterator end) + : begin_(pred, begin, end), end_(pred, end, end) {} + + /** + * @brief Returns an iterator to the first element that satisfies the predicate. + * + * @return filter_iter Iterator pointing to the first filtered element, + * or equal to end() if no elements satisfy the predicate. + */ + filter_iter begin() const { return begin_; } + + /** + * @brief Returns an iterator representing the end of the filtered range. + * + * @return filter_iter Past-the-end iterator for the filtered range. + */ + filter_iter end() const { return end_; } + + /** + * @brief Checks if the filtered range is empty. + * + * @return true if no elements in the range satisfy the predicate, false otherwise. + * + * @note This operation has O(1) complexity as it only compares iterators. + */ + bool empty() const { return begin_ == end_; } + + private: + filter_iter begin_; ///< Iterator to first element satisfying predicate + filter_iter end_; ///< Past-the-end iterator for the filtered range + }; + + /** + * @brief Factory function to create a filter_range with automatic template deduction. + * + * This convenience function eliminates the need to explicitly specify template parameters + * when creating a filter_range. The template parameters are automatically deduced from + * the function arguments. + * + * @tparam Predicate Automatically deduced predicate type + * @tparam Iterator Automatically deduced iterator type + * + * @param pred Predicate function/functor for filtering elements + * @param begin Iterator to the beginning of the range + * @param end Iterator to the end of the range + * + * @return filter_range A filter_range object configured with + * the provided predicate and range + * + * Example usage: + * @code + * std::vector words = {"hello", "world", "test", "example"}; + * + * // Filter strings longer than 4 characters + * auto long_words = LL::make_filter( + * [](const std::string& s) { return s.length() > 4; }, + * words.begin(), + * words.end() + * ); + * + * // Use with range-based for loop + * for (const auto& word : long_words) { + * std::cout << word << std::endl; // Prints: hello, world, example + * } + * + * // Use with STL algorithms + * auto count = std::distance(long_words.begin(), long_words.end()); + * std::cout << "Found " << count << " long words." << std::endl; + * @endcode + * + * @note This function is preferred over direct construction of filter_range + * for most use cases due to automatic template parameter deduction. + */ + template + filter_range make_filter(Predicate pred, Iterator begin, Iterator end) + { + return filter_range(pred, begin, end); + } + + /** + * @brief Create a filter_range over an entire container with automatic template deduction. + * + * This convenience function creates a filtered view over an entire container without + * requiring explicit begin() and end() calls. It automatically handles both const and + * non-const containers, preserving constness in the resulting iterator types. + * + * @tparam Predicate Automatically deduced predicate type + * @tparam Container Automatically deduced container type (const or non-const) + * + * @param pred Predicate function/functor for filtering elements + * @param container The container to filter (can be const or non-const) + * + * @return filter_range with appropriate iterator type for the container + * + * Example usage: + * @code + * // Non-const container + * std::vector numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + * auto evens = LL::make_filter([](int n) { return n % 2 == 0; }, numbers); + * + * // Const container + * const std::list words = {"cat", "elephant", "dog", "hippopotamus"}; + * auto long_words = LL::make_filter([](const std::string& s) { return s.size() > 3; }, words); + * + * // Works with any container that supports begin()/end() + * std::set values = {1.1, 2.2, 3.3, 4.4, 5.5}; + * auto large_values = LL::make_filter([](double d) { return d > 3.0; }, values); + * + * // Use with range-based for loops + * for (const auto& word : long_words) { + * std::cout << word << " "; // Prints: elephant hippopotamus + * } + * + * // Chain with STL algorithms + * auto even_count = std::distance(evens.begin(), evens.end()); + * std::cout << "Found " << even_count << " even numbers." << std::endl; + * @endcode + * + * @note This overload automatically calls begin() and end() on the container, + * making it more convenient than the iterator-based version. + * @note The container must remain valid for the lifetime of the returned filter_range. + * @note Constness of the container is preserved in the iterator type. + */ + template + filter_range()))> + make_filter(Predicate pred, Container&& container) + { + return filter_range()))>( + pred, std::begin(container), std::end(container)); + } + +} // namespace LL #endif // LL_LLSTL_H diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 3f33ad61c54..21b11c53112 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -192,6 +192,9 @@ LLOSInfo::LLOSInfo() : GetSystemInfo(&si); //if it fails get regular system info //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load) +#pragma warning(push) +#pragma warning(disable : 4996) // ignore 'deprecated.' GetVersionEx is deprecated + // Try calling GetVersionEx using the OSVERSIONINFOEX structure. OSVERSIONINFOEX osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); @@ -210,6 +213,8 @@ LLOSInfo::LLOSInfo() : } } +#pragma warning(pop) + S32 ubr = 0; // Windows 10 Update Build Revision, can be retrieved from a registry if (mMajorVer == 10) { @@ -1323,7 +1328,7 @@ bool gunzip_file(const std::string& srcfile, const std::string& dstfile) S32 bytes = 0; tmpfile = dstfile + ".t"; #ifdef LL_WINDOWS - llutf16string utf16filename = utf8str_to_utf16str(srcfile); + std::wstring utf16filename = ll_convert(srcfile); src = gzopen_w(utf16filename.c_str(), "rb"); #else src = gzopen(srcfile.c_str(), "rb"); @@ -1367,7 +1372,7 @@ bool gzip_file(const std::string& srcfile, const std::string& dstfile) tmpfile = dstfile + ".t"; #ifdef LL_WINDOWS - llutf16string utf16filename = utf8str_to_utf16str(tmpfile); + std::wstring utf16filename = ll_convert(tmpfile); dst = gzopen_w(utf16filename.c_str(), "wb"); #else dst = gzopen(tmpfile.c_str(), "wb"); diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 034e3f78974..1a1d06a6fd7 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -452,7 +452,9 @@ ElementT LLThreadSafeQueue::pop(void) // so we can finish draining the queue. pop_result popped = pop_(lock1, value); if (popped == POPPED) - return std::move(value); + // don't use std::move when returning local value because + // it prevents the compiler from optimizing with copy elision + return value; // Once the queue is DONE, there will never be any more coming. if (popped == DONE) diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp index a3ce7f8e3dd..3f990415924 100644 --- a/indra/llcommon/tests/stringize_test.cpp +++ b/indra/llcommon/tests/stringize_test.cpp @@ -110,6 +110,17 @@ namespace tut void stringize_object::test<3>() { //Tests rely on validity of wstring_to_utf8str() +#if LL_WINDOWS // Windows wstring is a 2byte UTF16 type + ensure_equals(ll_convert(wstringize(c)), ll_convert(std::wstring(L"c"))); + ensure_equals(ll_convert(wstringize(s)), ll_convert(std::wstring(L"17"))); + ensure_equals(ll_convert(wstringize(i)), ll_convert(std::wstring(L"34"))); + ensure_equals(ll_convert(wstringize(l)), ll_convert(std::wstring(L"68"))); + ensure_equals(ll_convert(wstringize(f)), ll_convert(std::wstring(L"3.14159"))); + ensure_equals(ll_convert(wstringize(d)), ll_convert(std::wstring(L"3.14159"))); + ensure_equals(ll_convert(wstringize(abc)), ll_convert(std::wstring(L"abc def"))); + ensure_equals(ll_convert(wstringize(abc)), ll_convert(wstringize(abc.c_str()))); + ensure_equals(ll_convert(wstringize(def)), ll_convert(std::wstring(L"def ghi"))); +#else ensure_equals(wstring_to_utf8str(wstringize(c)), wstring_to_utf8str(L"c")); ensure_equals(wstring_to_utf8str(wstringize(s)), wstring_to_utf8str(L"17")); ensure_equals(wstring_to_utf8str(wstringize(i)), wstring_to_utf8str(L"34")); @@ -119,6 +130,7 @@ namespace tut ensure_equals(wstring_to_utf8str(wstringize(abc)), wstring_to_utf8str(L"abc def")); ensure_equals(wstring_to_utf8str(wstringize(abc)), wstring_to_utf8str(wstringize(abc.c_str()))); ensure_equals(wstring_to_utf8str(wstringize(def)), wstring_to_utf8str(L"def ghi")); +#endif // ensure_equals(wstring_to_utf8str(wstringize(llsd)), wstring_to_utf8str(L"{'abc':'abc def','d':r3.14159,'i':i34}")); } } // namespace tut diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 05b788a4338..fa37d231263 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -12,6 +12,7 @@ include(LLAddBuildTest) include(LLCommon) include(Tut) include(bugsplat) +include(websocketpp) set(llcorehttp_SOURCE_FILES bufferarray.cpp @@ -23,6 +24,8 @@ set(llcorehttp_SOURCE_FILES httprequest.cpp httpresponse.cpp httpstats.cpp + llwebsocketmgr.cpp + lljsonrpcws.cpp _httplibcurl.cpp _httpopcancel.cpp _httpoperation.cpp @@ -51,6 +54,8 @@ set(llcorehttp_HEADER_FILES httprequest.h httpresponse.h httpstats.h + llwebsocketmgr.h + lljsonrpcws.h _httpinternal.h _httplibcurl.h _httpopcancel.h @@ -85,6 +90,7 @@ target_link_libraries( ll::libcurl ll::openssl ll::nghttp2 + ll::websocketpp ) target_include_directories( llcorehttp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # llmessage depends on llcorehttp, yet llcorehttp also depends on llmessage (at least for includes). @@ -131,7 +137,7 @@ if (LL_TESTS AND LLCOREHTTP_TESTS) ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llcorehttp_peer.py" ) - + # # Example Programs # diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 6186e7a308b..081a4d9bac9 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -538,6 +538,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) long sslHostV(0L); long dnsCacheTimeout(-1L); long nobody(0L); + curl_off_t lastModified(0L); if (mReqOptions) { @@ -546,6 +547,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L; dnsCacheTimeout = mReqOptions->getDNSCacheTimeout(); nobody = mReqOptions->getHeadersOnly() ? 1L : 0L; + lastModified = (curl_off_t)mReqOptions->getLastModified(); } check_curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect); @@ -554,6 +556,17 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) check_curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody); + if (lastModified) + { + check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); +#if (LIBCURL_VERSION_NUM >= 0x073B00) + // requires curl 7.59.0 + check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE_LARGE, lastModified); +#else + check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE, (long)lastModified); +#endif + } + // The Linksys WRT54G V5 router has an issue with frequent // DNS lookups from LAN machines. If they happen too often, // like for every HTTP request, the router gets annoyed after diff --git a/indra/llcorehttp/examples/http_texture_load.cpp b/indra/llcorehttp/examples/http_texture_load.cpp index 72e0c29a243..986e675d00e 100644 --- a/indra/llcorehttp/examples/http_texture_load.cpp +++ b/indra/llcorehttp/examples/http_texture_load.cpp @@ -52,8 +52,6 @@ void init_curl(); void term_curl(); -void ssl_thread_id_callback(CRYPTO_THREADID*); -void ssl_locking_callback(int mode, int type, const char * file, int line); void usage(std::ostream & out); // Default command line settings @@ -606,63 +604,15 @@ void WorkingSet::loadAssetUuids(FILE * in) } -int ssl_mutex_count(0); -LLCoreInt::HttpMutex ** ssl_mutex_list = NULL; - void init_curl() { curl_global_init(CURL_GLOBAL_ALL); - - ssl_mutex_count = CRYPTO_num_locks(); - if (ssl_mutex_count > 0) - { - ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count]; - - for (int i(0); i < ssl_mutex_count; ++i) - { - ssl_mutex_list[i] = new LLCoreInt::HttpMutex; - } - - CRYPTO_set_locking_callback(ssl_locking_callback); - CRYPTO_THREADID_set_callback(ssl_thread_id_callback); - } } void term_curl() { - CRYPTO_set_locking_callback(NULL); - for (int i(0); i < ssl_mutex_count; ++i) - { - delete ssl_mutex_list[i]; - } - delete [] ssl_mutex_list; -} - - -void ssl_thread_id_callback(CRYPTO_THREADID* pthreadid) -{ -#if defined(WIN32) - CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread()); -#else - CRYPTO_THREADID_set_pointer(pthreadid, pthread_self()); -#endif -} - - -void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */) -{ - if (type >= 0 && type < ssl_mutex_count) - { - if (mode & CRYPTO_LOCK) - { - ssl_mutex_list[type]->lock(); - } - else - { - ssl_mutex_list[type]->unlock(); - } - } + curl_global_cleanup(); } diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp index d85f6039b1c..5abd28e2112 100644 --- a/indra/llcorehttp/httpoptions.cpp +++ b/indra/llcorehttp/httpoptions.cpp @@ -47,6 +47,7 @@ HttpOptions::HttpOptions() : mVerifyPeer(sDefaultVerifyPeer), mVerifyHost(false), mDNSCacheTimeout(-1L), + mLastModified(0), mNoBody(false) {} @@ -129,6 +130,11 @@ void HttpOptions::setHeadersOnly(bool nobody) } } +void HttpOptions::setLastModified(time_t lastModified) +{ + mLastModified = lastModified; +} + void HttpOptions::setDefaultSSLVerifyPeer(bool verify) { sDefaultVerifyPeer = verify; diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h index 56a28013cb4..fdb277c66ef 100644 --- a/indra/llcorehttp/httpoptions.h +++ b/indra/llcorehttp/httpoptions.h @@ -178,6 +178,13 @@ class HttpOptions : private boost::noncopyable return mNoBody; } + // Default: 0 + void setLastModified(time_t lastModified); + time_t getLastModified() const + { + return mLastModified; + } + /// Sets default behavior for verifying that the name in the /// security certificate matches the name of the host contacted. /// Defaults false if not set, but should be set according to @@ -199,6 +206,7 @@ class HttpOptions : private boost::noncopyable bool mVerifyHost; int mDNSCacheTimeout; bool mNoBody; + time_t mLastModified; static bool sDefaultVerifyPeer; }; // end class HttpOptions diff --git a/indra/llcorehttp/llhttpconstants.cpp b/indra/llcorehttp/llhttpconstants.cpp index 40d6c7506c2..7a671543d93 100755 --- a/indra/llcorehttp/llhttpconstants.cpp +++ b/indra/llcorehttp/llhttpconstants.cpp @@ -100,6 +100,7 @@ const std::string HTTP_IN_HEADER_LOCATION("location"); const std::string HTTP_IN_HEADER_RETRY_AFTER("retry-after"); const std::string HTTP_IN_HEADER_SET_COOKIE("set-cookie"); const std::string HTTP_IN_HEADER_USER_AGENT("user-agent"); +const std::string HTTP_IN_HEADER_X_CONTENT_TYPE_OPTIONS("x-content-type-options"); const std::string HTTP_IN_HEADER_X_FORWARDED_FOR("x-forwarded-for"); const std::string HTTP_CONTENT_LLSD_XML("application/llsd+xml"); @@ -122,6 +123,7 @@ const std::string HTTP_CONTENT_IMAGE_BMP("image/bmp"); const std::string HTTP_NO_CACHE("no-cache"); const std::string HTTP_NO_CACHE_CONTROL("no-cache, max-age=0"); +const std::string HTTP_NOSNIFF("nosniff"); const std::string HTTP_VERB_INVALID("(invalid)"); const std::string HTTP_VERB_HEAD("HEAD"); diff --git a/indra/llcorehttp/llhttpconstants.h b/indra/llcorehttp/llhttpconstants.h index 583f9fbcb77..71c1dfa1730 100755 --- a/indra/llcorehttp/llhttpconstants.h +++ b/indra/llcorehttp/llhttpconstants.h @@ -190,6 +190,7 @@ extern const std::string HTTP_IN_HEADER_LOCATION; extern const std::string HTTP_IN_HEADER_RETRY_AFTER; extern const std::string HTTP_IN_HEADER_SET_COOKIE; extern const std::string HTTP_IN_HEADER_USER_AGENT; +extern const std::string HTTP_IN_HEADER_X_CONTENT_TYPE_OPTIONS; extern const std::string HTTP_IN_HEADER_X_FORWARDED_FOR; //// HTTP Content Types //// @@ -215,5 +216,6 @@ extern const std::string HTTP_CONTENT_IMAGE_BMP; //// HTTP Cache Settings //// extern const std::string HTTP_NO_CACHE; extern const std::string HTTP_NO_CACHE_CONTROL; +extern const std::string HTTP_NOSNIFF; #endif diff --git a/indra/llcorehttp/lljsonrpcws.cpp b/indra/llcorehttp/lljsonrpcws.cpp new file mode 100644 index 00000000000..93e38a8397c --- /dev/null +++ b/indra/llcorehttp/lljsonrpcws.cpp @@ -0,0 +1,628 @@ +/** + * @file lljsonrpcws.cpp + * @brief JSON-RPC 2.0 WebSocket server and connection implementation + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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 "lljsonrpcws.h" +#include "llerror.h" +#include "llsdjson.h" +#include "lldate.h" + +#include + +//======================================================================== +// LLJSONRPCConnection Implementation +//======================================================================== + +void LLJSONRPCConnection::onOpen() +{ + LL_INFOS("JSONRPC") << "JSON-RPC connection opened" << LL_ENDL; +} + +void LLJSONRPCConnection::onClose() +{ + LL_INFOS("JSONRPC") << "JSON-RPC connection closed, clearing " + << mPendingRequests.size() << " pending requests" << LL_ENDL; + + // Cancel all pending requests + for (auto& [id, callback] : mPendingRequests) + { + if (callback) + { + LLSD error; + error["code"] = RPCError::CONNECTION_CLOSED; // Use named constant instead of magic number + error["message"] = "Connection closed"; + callback(LLSD(), error); + } + } + mPendingRequests.clear(); +} + +void LLJSONRPCConnection::onMessage(const std::string& message) +{ + LL_DEBUGS("JSONRPC") << "Received JSON-RPC message: " << message << LL_ENDL; + + try + { + // Parse JSON message + boost::system::error_code ec; + boost::json::value json_value = boost::json::parse(message, ec); + + if (ec.failed()) + { + LL_WARNS("JSONRPC") << "Failed to parse JSON: " << ec.message() << LL_ENDL; + sendError(LLSD(), ParseError(ec.message())); + return; + } + + // Convert to LLSD + LLSD message_obj = LlsdFromJson(json_value); + + // Handle batch vs single message + if (message_obj.isArray()) + { + // Batch request + if (message_obj.size() == 0) + { + sendError(LLSD(), InvalidRequest("Empty batch")); + return; + } + + // Process each message in the batch + for (S32 i = 0; i < message_obj.size(); ++i) + { + processMessage(message_obj[i]); + } + } + else + { + // Single message + processMessage(message_obj); + } + } + catch (const std::exception& e) + { + LL_WARNS("JSONRPC") << "Exception processing JSON-RPC message: " << e.what() << LL_ENDL; + sendError(LLSD(), InternalError(e.what())); + } +} + +void LLJSONRPCConnection::processMessage(const LLSD& message_obj) +{ + try + { + // Determine if this is a request, notification, or response + if (message_obj.has("method")) + { + // This is a request or notification + if (validateMessage(message_obj, true)) + { + processRequest(message_obj); + } + } + else if (message_obj.has("result") || message_obj.has("error")) + { + // This is a response + if (validateMessage(message_obj, false)) + { + processResponse(message_obj); + } + } + else + { + LL_WARNS("JSONRPC") << "Message must contain 'method' or 'result'/'error'" << LL_ENDL; + } + } + catch (const RPCError& e) + { + LLSD id = message_obj.has("id") ? message_obj["id"] : LLSD(); + sendError(id, e); + } +} + +void LLJSONRPCConnection::processRequest(const LLSD& request) +{ + std::string method = request["method"].asString(); + LLSD params = request.has("params") ? request["params"] : LLSD(); + LLSD id = request.has("id") ? request["id"] : LLSD(); + bool is_notification = !request.has("id"); + + LL_DEBUGS("JSONRPC") << "Processing " << (is_notification ? "notification" : "request") + << " for method: " << method << LL_ENDL; + + // Find method handler + auto it = mMethodHandlers.find(method); + if (it == mMethodHandlers.end()) + { + if (!is_notification) + { + sendError(id, MethodNotFound(method)); + } + return; + } + + try + { + // Call the method handler with method name, ID, and parameters + LLSD result = it->second(method, id, params); + + if (!is_notification) + { + sendResponse(id, result); + } + } + catch (const RPCError& e) + { + if (!is_notification) + { + sendError(id, e); + } + else + { + LL_WARNS("JSONRPC") << "Error in notification handler for " << method + << ": " << e.what() << LL_ENDL; + } + } + catch (const std::exception& e) + { + if (!is_notification) + { + sendError(id, InternalError(e.what())); + } + else + { + LL_WARNS("JSONRPC") << "Exception in notification handler for " << method + << ": " << e.what() << LL_ENDL; + } + } +} + +void LLJSONRPCConnection::processResponse(const LLSD& response) +{ + if (!response.has("id")) + { + LL_WARNS("JSONRPC") << "Response missing id field" << LL_ENDL; + return; + } + + std::string id = response["id"].asString(); + auto it = mPendingRequests.find(id); + if (it == mPendingRequests.end()) + { + LL_WARNS("JSONRPC") << "Received response for unknown request id: " << id << LL_ENDL; + return; + } + + ResponseCallback callback = it->second; + mPendingRequests.erase(it); + + if (callback) + { + LLSD result = response.has("result") ? response["result"] : LLSD(); + LLSD error = response.has("error") ? response["error"] : LLSD(); + + callback(result, error); + } +} + +bool LLJSONRPCConnection::validateMessage(const LLSD& message, bool is_request) +{ + // Check JSON-RPC version + if (!message.has("jsonrpc") || message["jsonrpc"].asString() != "2.0") + { + LL_WARNS("JSONRPC") << "Missing or invalid jsonrpc version" << LL_ENDL; + return false; + } + + if (is_request) + { + // Request/notification validation + if (!message.has("method")) + { + LL_WARNS("JSONRPC") << "Missing method field" << LL_ENDL; + return false; + } + + if (!message["method"].isString()) + { + LL_WARNS("JSONRPC") << "Method must be a string" << LL_ENDL; + return false; + } + + // Params are optional but must be array or object if present + if (message.has("params")) + { + if (!message["params"].isArray() && !message["params"].isMap()) + { + LL_WARNS("JSONRPC") << "Params must be array or object" << LL_ENDL; + return false; + } + } + } + else + { + // Response validation + if (!message.has("id")) + { + LL_WARNS("JSONRPC") << "Response missing id field" << LL_ENDL; + return false; + } + + // Must have either result or error, but not both + bool has_result = message.has("result"); + bool has_error = message.has("error"); + + if (!has_result && !has_error) + { + LL_WARNS("JSONRPC") << "Response must have result or error" << LL_ENDL; + return false; + } + + if (has_result && has_error) + { + LL_WARNS("JSONRPC") << "Response cannot have both result and error" << LL_ENDL; + return false; + } + + // Error must be an object with code and message + if (has_error) + { + LLSD error = message["error"]; + if (!error.isMap()) + { + LL_WARNS("JSONRPC") << "Error must be an object" << LL_ENDL; + } + if (!error.has("code") || !error.has("message")) + { + LL_WARNS("JSONRPC") << "Error must have code and message" << LL_ENDL; + } + } + } + return true; +} + +LLSD LLJSONRPCConnection::generateId() +{ + // Server-wide atomic counter for efficient unique ID generation + // Start from 1000 to avoid conflicts with any manual test IDs + static std::atomic sRequestIdCounter{1000}; + + // Generate server-unique sequential ID + U64 id = sRequestIdCounter.fetch_add(1); + return LLSD(llformat("rpc_%llu", id)); +} + +void LLJSONRPCConnection::registerMethod(const std::string& method, MethodHandler handler) +{ + mMethodHandlers[method] = handler; + LL_DEBUGS("JSONRPC") << "Registered method: " << method << LL_ENDL; +} + +void LLJSONRPCConnection::unregisterMethod(const std::string& method) +{ + mMethodHandlers.erase(method); + LL_DEBUGS("JSONRPC") << "Unregistered method: " << method << LL_ENDL; +} + +LLSD LLJSONRPCConnection::call(const std::string& method, const LLSD& params, ResponseCallback callback) +{ + LLSD request; + request["jsonrpc"] = "2.0"; + request["method"] = method; + + if (!params.isUndefined()) + { + request["params"] = params; + } + + LLSD id = generateId(); + request["id"] = id; + + // Store callback if provided + if (callback) + { + mPendingRequests[id.asString()] = callback; + } + + // Send the request + if (!sendMessage(LlsdToJson(request))) + { + // Remove from pending if send failed + if (callback) + { + mPendingRequests.erase(id.asString()); + } + LL_WARNS("JSONRPC") << "Failed to send request" << LL_ENDL; + return LLSD(); + } + + LL_DEBUGS("JSONRPC") << "Sent request: " << method << " with id: " << id.asString() << LL_ENDL; + return id; +} + +bool LLJSONRPCConnection::notify(const std::string& method, const LLSD& params) +{ + LLSD notification; + notification["jsonrpc"] = "2.0"; + notification["method"] = method; + + if (!params.isUndefined()) + { + notification["params"] = params; + } + + // Notifications don't have an id + + if (!sendMessage(LlsdToJson(notification))) + { + LL_WARNS("JSONRPC") << "Failed to send notification" << LL_ENDL; + return false; + } + + LL_DEBUGS("JSONRPC") << "Sent notification: " << method << LL_ENDL; + return true; +} + +bool LLJSONRPCConnection::sendResponse(const LLSD& id, const LLSD& result) +{ + LLSD response; + response["jsonrpc"] = "2.0"; + response["result"] = result; + response["id"] = id; + + if (!sendMessage(LlsdToJson(response))) + { + LL_WARNS("JSONRPC") << "Failed to send response for id: " << id.asString() << LL_ENDL; + return false; + } + LL_DEBUGS("JSONRPC") << "Sent response for id: " << id.asString() << LL_ENDL; + return true; +} + +bool LLJSONRPCConnection::sendError(const LLSD& id, const RPCError& error) +{ + LLSD response; + response["jsonrpc"] = "2.0"; + + LLSD error_obj; + error_obj["code"] = error.getCode(); + error_obj["message"] = error.what(); + + if (!error.getData().isUndefined()) + { + error_obj["data"] = error.getData(); + } + + response["error"] = error_obj; + response["id"] = id.isUndefined() ? LLSD() : id; // null for parse errors + + if (!sendMessage(LlsdToJson(response))) + { + LL_WARNS("JSONRPC") << "Failed to send error response" << LL_ENDL; + return false; + } + LL_DEBUGS("JSONRPC") << "Sent error response: " << error.what() << LL_ENDL; + return true; +} + +bool LLJSONRPCConnection::sendBatch(const LLSD& batch, ResponseCallback callback) +{ + if (!batch.isArray() || batch.size() == 0) + { + LL_WARNS("JSONRPC") << "Batch must be non-empty array" << LL_ENDL; + return false; + } + + // For batch requests with callbacks, we need to track multiple responses + // This is complex as we need to correlate all responses before calling callback + // For now, we'll send the batch but won't support batch response callbacks + if (callback) + { + LL_WARNS("JSONRPC") << "Batch response callbacks not yet implemented" << LL_ENDL; + } + + if (!sendMessage(LlsdToJson(batch))) + { + LL_WARNS("JSONRPC") << "Failed to send batch" << LL_ENDL; + return false; + } + + LL_DEBUGS("JSONRPC") << "Sent batch with " << batch.size() << " messages" << LL_ENDL; + return true; +} + +//======================================================================== +// LLJSONRPCServer Implementation +//======================================================================== + +LLJSONRPCServer::LLJSONRPCServer(const std::string& name, U16 port, bool local_only) + : LLWebsocketMgr::WSServer(name, port, local_only), mServerName(name) +{ + LL_INFOS("JSONRPC") << "Created JSON-RPC server: " << name + << " on port " << port << LL_ENDL; + + // Register standard JSON-RPC methods + registerGlobalMethod("system.listMethods", [this](const std::string& method, const LLSD& id, const LLSD& params) -> LLSD { + LL_DEBUGS("JSONRPC") << "System method " << method << " called" << LL_ENDL; + return getMethodList(); + }); + + registerGlobalMethod("system.getStats", [this](const std::string& method, const LLSD& id, const LLSD& params) -> LLSD { + LL_DEBUGS("JSONRPC") << "System method " << method << " called" << LL_ENDL; + return getServerStats(); + }); + + registerGlobalMethod("system.ping", [](const std::string& method, const LLSD& id, const LLSD& params) -> LLSD { + LL_DEBUGS("JSONRPC") << "System method " << method << " called" << LL_ENDL; + LLSD result; + result["pong"] = LLDate::now().asString(); + result["params"] = params; + return result; + }); +} + +LLWebsocketMgr::WSConnection::ptr_t LLJSONRPCServer::connectionFactory(LLWebsocketMgr::WSServer::ptr_t server, + LLWebsocketMgr::connection_h handle) +{ + auto connection = std::make_shared(server, handle); + setupConnectionMethods(connection); + return connection; +} + +void LLJSONRPCServer::onConnectionOpened(const LLWebsocketMgr::WSConnection::ptr_t& connection) +{ + LL_INFOS("JSONRPC") << "JSON-RPC client connected, total connections: " + << getConnectionCount() << LL_ENDL; +} + +void LLJSONRPCServer::onConnectionClosed(const LLWebsocketMgr::WSConnection::ptr_t& connection) +{ + LL_INFOS("JSONRPC") << "JSON-RPC client disconnected, total connections: " + << getConnectionCount() << LL_ENDL; +} + +void LLJSONRPCServer::setupConnectionMethods(LLJSONRPCConnection::ptr_t connection) +{ + LLMutexLock lock(&mGlobalMethodsMutex); + + // Register all global methods on the new connection + for (const auto& [method, handler] : mGlobalMethods) + { + connection->registerMethod(method, handler); + } +} + +void LLJSONRPCServer::registerGlobalMethod(const std::string& method, MethodHandler handler) +{ + { + LLMutexLock lock(&mGlobalMethodsMutex); + mGlobalMethods[method] = handler; + } + + // Apply to all existing connections - we need to iterate through connections + // Since mConnections is private, we need to use broadcastMessage or find another approach + // For now, we'll only apply to new connections + + LL_INFOS("JSONRPC") << "Registered global method: " << method << LL_ENDL; +} + +void LLJSONRPCServer::unregisterGlobalMethod(const std::string& method) +{ + { + LLMutexLock lock(&mGlobalMethodsMutex); + mGlobalMethods.erase(method); + } + + // For existing connections, we would need access to them + // This is a limitation of the current design - methods added after connection + // establishment won't be retroactively applied + + LL_INFOS("JSONRPC") << "Unregistered global method: " << method << LL_ENDL; +} + +LLSD LLJSONRPCServer::getMethodList() const +{ + LLMutexLock lock(&mGlobalMethodsMutex); + + LLSD methods = LLSD::emptyArray(); + for (const auto& [method, handler] : mGlobalMethods) + { + methods.append(method); + } + + return methods; +} + +void LLJSONRPCServer::broadcastNotification(const std::string& method, const LLSD& params) +{ + // Use custom broadcast logic since we need to call notify() on each JSON-RPC connection + // We can't use the base broadcastMessage() because we need structured JSON-RPC messages + + // Create the notification message + LLSD notification; + notification["jsonrpc"] = "2.0"; + notification["method"] = method; + if (!params.isUndefined()) + { + notification["params"] = params; + } + + // Use the base class broadcast functionality + broadcastMessage(boost::json::serialize(LlsdToJson(notification))); + + mTotalNotificationsSent += getConnectionCount(); + LL_DEBUGS("JSONRPC") << "Broadcast notification: " << method + << " to " << getConnectionCount() << " clients" << LL_ENDL; +} + +void LLJSONRPCServer::broadcastCall(const std::string& method, const LLSD& params, + BatchResponseCallback callback) +{ + if (callback) + { + LL_WARNS("JSONRPC") << "Broadcast call response callbacks not yet implemented" << LL_ENDL; + } + + // Create the request message with a server-unique ID + LLSD request; + request["jsonrpc"] = "2.0"; + request["method"] = method; + + // Use the same ID generation as connections for consistency + static std::atomic sBroadcastIdCounter{10000000}; // Start at 10M to clearly distinguish from regular requests + U64 id = sBroadcastIdCounter.fetch_add(1); + request["id"] = LLSD(llformat("broadcast_%llu", id)); + + if (!params.isUndefined()) + { + request["params"] = params; + } + + // Use the base class broadcast functionality + broadcastMessage(boost::json::serialize(LlsdToJson(request))); + + LL_DEBUGS("JSONRPC") << "Broadcast call: " << method + << " to " << getConnectionCount() << " clients" << LL_ENDL; +} + +LLSD LLJSONRPCServer::getServerStats() const +{ + LLSD stats; + stats["server_name"] = mServerName; + stats["connection_count"] = static_cast(getConnectionCount()); + stats["is_running"] = isRunning(); + + { + LLMutexLock lock(&mGlobalMethodsMutex); + stats["global_method_count"] = static_cast(mGlobalMethods.size()); + } + + stats["total_requests_handled"] = static_cast(mTotalRequestsHandled.load()); + stats["total_notifications_sent"] = static_cast(mTotalNotificationsSent.load()); + stats["uptime"] = LLDate::now().asString(); + + return stats; +} diff --git a/indra/llcorehttp/lljsonrpcws.h b/indra/llcorehttp/lljsonrpcws.h new file mode 100644 index 00000000000..bd9939aa339 --- /dev/null +++ b/indra/llcorehttp/lljsonrpcws.h @@ -0,0 +1,461 @@ +/** + * @file lljsonrpcws.h + * @brief JSON-RPC 2.0 WebSocket server and connection implementation + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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$ + */ + +#pragma once + +#include "llwebsocketmgr.h" +#include "llsd.h" +#include "lluuid.h" + +#include +#include +#include + +/** + * @class LLJSONRPCConnection + * @brief JSON-RPC 2.0 WebSocket connection implementation + * + * This class implements the JSON-RPC 2.0 protocol over WebSocket connections. + * It handles request/response patterns, notifications, method registration, + * and error handling according to the JSON-RPC 2.0 specification. + * + * ## JSON-RPC 2.0 Protocol Features + * + * - **Requests**: Method calls that expect a response + * - **Notifications**: Method calls that do not expect a response + * - **Batch Operations**: Multiple requests/notifications in a single message + * - **Error Handling**: Standardized error codes and messages + * - **ID Correlation**: Request/response correlation using unique identifiers + * + * ## Method Handler Registration + * + * Methods use an enhanced handler signature that provides method name and request ID context: + * + * @code + * connection->registerMethod("echo", [](const std::string& method, const LLSD& id, const LLSD& params) -> LLSD { + * LL_INFOS("JSONRPC") << "Method " << method << " called with ID " << id.asString() << LL_ENDL; + * return params; // Echo back the parameters + * }); + * + * connection->registerMethod("add", [](const std::string& method, const LLSD& id, const LLSD& params) -> LLSD { + * if (params.isArray() && params.size() >= 2) { + * LL_INFOS("JSONRPC") << "Adding numbers via " << method << LL_ENDL; + * return params[0].asReal() + params[1].asReal(); + * } + * throw LLJSONRPCConnection::InvalidParams("Expected array with 2 numbers"); + * }); + * @endcode + * + * The enhanced signature enables: + * - Method context awareness for shared handlers + * - Request correlation and distributed tracing + * - Distinction between notifications (id undefined) and requests + * - Enhanced logging and error reporting with context + * + * ## Making RPC Calls + * + * @code + * // Asynchronous request with callback + * LLSD params; + * params.append(5); + * params.append(3); + * connection->call("add", params, [](const LLSD& result, const LLSD& error) { + * if (error.isUndefined()) { + * LL_INFOS() << "Result: " << result.asReal() << LL_ENDL; + * } else { + * LL_WARNS() << "Error: " << error["message"].asString() << LL_ENDL; + * } + * }); + * + * // Fire-and-forget notification + * connection->notify("log", LLSD("Server started")); + * @endcode + */ +class LLJSONRPCConnection : public LLWebsocketMgr::WSConnection +{ +public: + using ptr_t = std::shared_ptr; + + /// Method handler function signature + /// @param method The method name that was called + /// @param id The request ID (undefined for notifications) + /// @param params The parameters passed to the method + /// @return The result to return to the caller + /// @throw RPCError-derived exceptions for error responses + using MethodHandler = std::function; + + /// Response callback function signature + /// @param result The result from a successful call (undefined if error occurred) + /// @param error The error object if call failed (undefined if successful) + using ResponseCallback = std::function; + + /** + * @brief JSON-RPC error base class + */ + class RPCError : public std::runtime_error + { + public: + // JSON-RPC 2.0 Standard Error Codes + static constexpr S32 PARSE_ERROR = -32700; ///< Invalid JSON was received by the server + static constexpr S32 INVALID_REQUEST = -32600; ///< The JSON sent is not a valid Request object + static constexpr S32 METHOD_NOT_FOUND = -32601; ///< The method does not exist / is not available + static constexpr S32 INVALID_PARAMS = -32602; ///< Invalid method parameter(s) + static constexpr S32 INTERNAL_ERROR = -32603; ///< Internal JSON-RPC error + + // Server Error Range (-32000 to -32099) + static constexpr S32 SERVER_ERROR_MIN = -32099; ///< Server error range minimum + static constexpr S32 SERVER_ERROR_MAX = -32000; ///< Server error range maximum + + // Common server-specific errors + static constexpr S32 CONNECTION_CLOSED = -32000; ///< Connection closed unexpectedly + static constexpr S32 REQUEST_TIMEOUT = -32001; ///< Request timed out + static constexpr S32 UNAUTHORIZED = -32002; ///< Authentication required + static constexpr S32 FORBIDDEN = -32003; ///< Access denied + static constexpr S32 RATE_LIMITED = -32004; ///< Too many requests + static constexpr S32 SERVICE_UNAVAILABLE = -32005; ///< Service temporarily unavailable + static constexpr S32 MESSAGE_TOO_LARGE = -32006; ///< Message exceeds maximum size + static constexpr S32 INVALID_SESSION = -32007; ///< Session expired or invalid + + RPCError(S32 code, const std::string& message, const LLSD& data = LLSD()) + : std::runtime_error(message), mCode(code), mData(data) {} + + S32 getCode() const { return mCode; } + const LLSD& getData() const { return mData; } + + protected: + S32 mCode; + LLSD mData; + }; + + /// Standard JSON-RPC error classes using named constants + class ParseError : public RPCError { + public: + ParseError(const std::string& details = "") + : RPCError(PARSE_ERROR, "Parse error" + (details.empty() ? "" : ": " + details)) {} + }; + + class InvalidRequest : public RPCError { + public: + InvalidRequest(const std::string& details = "") + : RPCError(INVALID_REQUEST, "Invalid Request" + (details.empty() ? "" : ": " + details)) {} + }; + + class MethodNotFound : public RPCError { + public: + MethodNotFound(const std::string& method = "") + : RPCError(METHOD_NOT_FOUND, "Method not found" + (method.empty() ? "" : ": " + method)) {} + }; + + class InvalidParams : public RPCError { + public: + InvalidParams(const std::string& details = "") + : RPCError(INVALID_PARAMS, "Invalid params" + (details.empty() ? "" : ": " + details)) {} + }; + + class InternalError : public RPCError { + public: + InternalError(const std::string& details = "") + : RPCError(INTERNAL_ERROR, "Internal error" + (details.empty() ? "" : ": " + details)) {} + }; + + /// Server-specific errors (in the -32000 to -32099 range) + class ConnectionClosedError : public RPCError { + public: + ConnectionClosedError(const std::string& details = "Connection closed") + : RPCError(CONNECTION_CLOSED, details) {} + }; + + class RequestTimeoutError : public RPCError { + public: + RequestTimeoutError(const std::string& details = "Request timed out") + : RPCError(REQUEST_TIMEOUT, details) {} + }; + + class UnauthorizedError : public RPCError { + public: + UnauthorizedError(const std::string& details = "Authentication required") + : RPCError(UNAUTHORIZED, details) {} + }; + + class ForbiddenError : public RPCError { + public: + ForbiddenError(const std::string& details = "Access denied") + : RPCError(FORBIDDEN, details) {} + }; + + class RateLimitedError : public RPCError { + public: + RateLimitedError(const std::string& details = "Too many requests") + : RPCError(RATE_LIMITED, details) {} + }; + + class ServiceUnavailableError : public RPCError { + public: + ServiceUnavailableError(const std::string& details = "Service temporarily unavailable") + : RPCError(SERVICE_UNAVAILABLE, details) {} + }; + + class MessageTooLargeError : public RPCError { + public: + MessageTooLargeError(const std::string& details = "Message exceeds maximum size") + : RPCError(MESSAGE_TOO_LARGE, details) {} + }; + + class InvalidSessionError : public RPCError { + public: + InvalidSessionError(const std::string& details = "Session expired or invalid") + : RPCError(INVALID_SESSION, details) {} + }; + + + LLJSONRPCConnection(const LLWebsocketMgr::WSServer::ptr_t server, + const LLWebsocketMgr::connection_h& handle) + : LLWebsocketMgr::WSConnection(server, handle) {} + + virtual ~LLJSONRPCConnection() = default; + + // WebSocket connection lifecycle + void onOpen() override; + void onClose() override; + void onMessage(const std::string& message) override; + + /** + * @brief Register a method handler + * @param method The method name to register + * @param handler The function to call when this method is invoked + */ + void registerMethod(const std::string& method, MethodHandler handler); + + /** + * @brief Unregister a method handler + * @param method The method name to unregister + */ + void unregisterMethod(const std::string& method); + + /** + * @brief Make an asynchronous JSON-RPC call + * @param method The method name to call + * @param params The parameters to pass + * @param callback Callback for the response (optional) + * @return The request ID for correlation + */ + LLSD call(const std::string& method, const LLSD& params = LLSD(), + ResponseCallback callback = nullptr); + + /** + * @brief Send a JSON-RPC notification (no response expected) + * @param method The method name + * @param params The parameters to pass + */ + bool notify(const std::string& method, const LLSD& params = LLSD()); + + /** + * @brief Send a successful response to a request + * @param id The request ID from the original request + * @param result The result to return + */ + bool sendResponse(const LLSD& id, const LLSD& result); + + /** + * @brief Send an error response to a request + * @param id The request ID from the original request (can be null) + * @param error The RPCError to send + */ + bool sendError(const LLSD& id, const RPCError& error); + + /** + * @brief Send a batch of requests/notifications + * @param batch Array of request/notification objects + * @param callback Callback for batch response (optional) + */ + bool sendBatch(const LLSD& batch, ResponseCallback callback = nullptr); + +protected: + /** + * @brief Process a single JSON-RPC message + * @param message_obj The parsed JSON message + */ + void processMessage(const LLSD& message_obj); + + /** + * @brief Process a JSON-RPC request + * @param request The request object + */ + void processRequest(const LLSD& request); + + /** + * @brief Process a JSON-RPC response + * @param response The response object + */ + void processResponse(const LLSD& response); + + /** + * @brief Validate a JSON-RPC message structure + * @param message The message to validate + * @param is_request True if validating a request, false for response + */ + bool validateMessage(const LLSD& message, bool is_request = true); + + /** + * @brief Generate the next unique request ID + * @return A server-unique request ID + * + * Generates a server-wide unique identifier using an atomic counter. + * This ensures request IDs are unique across all connections within the + * server instance, providing efficient ID generation with guaranteed uniqueness. + * + * IDs follow the format "rpc_{counter}" where counter is a monotonically + * increasing 64-bit value starting from 1. This approach provides: + * - Guaranteed uniqueness within server scope + * - High performance (atomic increment operation) + * - Predictable, sequential ordering for debugging + * - Thread-safe generation across multiple connections + */ + LLSD generateId(); + +private: + std::unordered_map mMethodHandlers; + std::unordered_map mPendingRequests; +}; + +/** + * @class LLJSONRPCServer + * @brief JSON-RPC 2.0 WebSocket server implementation + * + * This server extends the basic WebSocket server to provide JSON-RPC 2.0 + * protocol support. It manages JSON-RPC connections and provides server-wide + * method registration and broadcasting capabilities. + * + * ## Server-Wide Method Registration + * + * Methods can be registered at the server level and will be available + * on all connections: + * + * @code + * auto server = std::make_shared("rpc_server", 8080); + * + * server->registerGlobalMethod("getServerInfo", [](const std::string& method, const LLSD& id, const LLSD& params) -> LLSD { + * LL_INFOS("JSONRPC") << "Server info requested via " << method << LL_ENDL; + * LLSD info; + * info["name"] = "My RPC Server"; + * info["version"] = "1.0.0"; + * info["uptime"] = LLDate::now().secondsSinceEpoch(); + * return info; + * }); + * + * server->registerGlobalMethod("listMethods", [server](const std::string& method, const LLSD& id, const LLSD& params) -> LLSD { + * return server->getMethodList(); + * }); + * @endcode + * + * ## Broadcasting and Multi-client Operations + * + * @code + * // Broadcast notification to all connected clients + * server->broadcastNotification("serverAlert", LLSD("Server will restart in 5 minutes")); + * + * // Call a method on all clients and collect responses + * server->broadcastCall("getClientStatus", LLSD(), [](const LLSD& responses) { + * for (const auto& response : llsd::inArray(responses)) { + * LL_INFOS() << "Client status: " << response << LL_ENDL; + * } + * }); + * @endcode + */ +class LLJSONRPCServer : public LLWebsocketMgr::WSServer +{ +public: + using ptr_t = std::shared_ptr; + using MethodHandler = LLJSONRPCConnection::MethodHandler; + using ResponseCallback = LLJSONRPCConnection::ResponseCallback; + using BatchResponseCallback = std::function; + + LLJSONRPCServer(const std::string& name, U16 port, bool local_only = true); + virtual ~LLJSONRPCServer() = default; + + // Server lifecycle callbacks + void onConnectionOpened(const LLWebsocketMgr::WSConnection::ptr_t& connection) override; + void onConnectionClosed(const LLWebsocketMgr::WSConnection::ptr_t& connection) override; + + /** + * @brief Register a global method available on all connections + * @param method The method name to register + * @param handler The function to call when this method is invoked + */ + void registerGlobalMethod(const std::string& method, MethodHandler handler); + + /** + * @brief Unregister a global method + * @param method The method name to unregister + */ + void unregisterGlobalMethod(const std::string& method); + + /** + * @brief Get list of registered global methods + * @return Array of method names + */ + LLSD getMethodList() const; + + /** + * @brief Broadcast a notification to all connected clients + * @param method The method name + * @param params The parameters to pass + */ + void broadcastNotification(const std::string& method, const LLSD& params = LLSD()); + + /** + * @brief Call a method on all connected clients + * @param method The method name + * @param params The parameters to pass + * @param callback Callback to receive aggregated responses + */ + void broadcastCall(const std::string& method, const LLSD& params = LLSD(), + BatchResponseCallback callback = nullptr); + + /** + * @brief Get server statistics + * @return Statistics object with connection count, method count, etc. + */ + LLSD getServerStats() const; + +protected: + LLWebsocketMgr::WSConnection::ptr_t connectionFactory(LLWebsocketMgr::WSServer::ptr_t server, + LLWebsocketMgr::connection_h handle) override; + + /** + * @brief Apply global method handlers to a new connection + * @param connection The connection to configure + */ + virtual void setupConnectionMethods(LLJSONRPCConnection::ptr_t connection); + +private: + std::unordered_map mGlobalMethods; + mutable LLMutex mGlobalMethodsMutex; + + std::string mServerName; // Store server name for stats + std::atomic mTotalRequestsHandled{0}; + std::atomic mTotalNotificationsSent{0}; +}; diff --git a/indra/llcorehttp/llwebsocketmgr.cpp b/indra/llcorehttp/llwebsocketmgr.cpp new file mode 100644 index 00000000000..addd108b71b --- /dev/null +++ b/indra/llcorehttp/llwebsocketmgr.cpp @@ -0,0 +1,660 @@ +/** + * @file llwebsocketmgr.cpp + * @brief WebSocket manager singleton implementation + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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 "llwebsocketmgr.h" +#include "llerror.h" +#include "llsdserialize.h" +#include "llhost.h" +#include "llsdjson.h" + +#include +#include +#include +#include + +#include +#include +#include + +//------------------------------------------------------------------------ +namespace +{ + using Server_t = websocketpp::server; + using Client_t = websocketpp::client; + using Connection_t = websocketpp::connection; +} + +//------------------------------------------------------------------------ + +//------------------------------------------------------------------------ +// LLWebsocketMgr Implementation +// + +void LLWebsocketMgr::initSingleton() +{ } + +void LLWebsocketMgr::cleanupSingleton() +{ + stopAllServers(); +} + +void LLWebsocketMgr::update() +{ + std::vector stops; + + for (auto &[name, server] : mServers) + { + if (server && server->isRunning()) + { + if (!server->update()) + { + stops.push_back(server); + } + } + } + + for (const auto& server : stops) + { + if (server) + { + LL_DEBUGS("WebSocket") << "Stopping server: " << server->mServerName << LL_ENDL; + removeServer(server->mServerName); + } + } +} + + +LLWebsocketMgr::WSServer::ptr_t LLWebsocketMgr::findServerByName(const std::string &name) const +{ + auto it = mServers.find(std::string(name)); + if (it != mServers.end()) + { + return it->second; + } + return nullptr; +} + +bool LLWebsocketMgr::addServer(const LLWebsocketMgr::WSServer::ptr_t& server) +{ + if (!server) + { + LL_WARNS("WebSocket") << "Attempted to add a null server" << LL_ENDL; + return false; + } + + auto it = mServers.find(server->mServerName); + if (it != mServers.end()) + { + LL_WARNS("WebSocket") << "Server with name " << server->mServerName << " already exists" << LL_ENDL; + return false; + } + mServers[server->mServerName] = server; + LL_INFOS("WebSocket") << "Added WebSocket server: " << server->mServerName << LL_ENDL; + return true; +} + +bool LLWebsocketMgr::removeServer(const std::string& name) +{ + auto it = mServers.find(name); + if (it == mServers.end()) + { + LL_WARNS("WebSocket") << "No server found with name " << name << " to remove" << LL_ENDL; + return false; + } + if (it->second && it->second->isRunning()) + it->second->stop(); + mServers.erase(it); + LL_INFOS("WebSocket") << "Removed WebSocket server: " << name << LL_ENDL; + return true; +} + + +bool LLWebsocketMgr::startServer(const std::string &name) const +{ + LLWebsocketMgr::WSServer::ptr_t server = findServerByName(name); + if (!server) + { + LL_WARNS("WebSocket") << "No server found with name " << name << " to start" << LL_ENDL; + return false; + } + if (server->isRunning()) + { + LL_WARNS("WebSocket") << "Server " << name << " is already running" << LL_ENDL; + return false; + } + return server->start(); +} + +void LLWebsocketMgr::stopServer(const std::string& name) const +{ + LLWebsocketMgr::WSServer::ptr_t server = findServerByName(name); + if (!server) + { + LL_WARNS("WebSocket") << "No server found with name " << name << " to stop" << LL_ENDL; + return; + } + if (!server->isRunning()) + { + LL_WARNS("WebSocket") << "Server " << name << " is not running" << LL_ENDL; + return; + } + server->stop(); +} + +void LLWebsocketMgr::stopAllServers() +{ + for (auto &[name, server] : mServers) + { + if (server && server->isRunning()) + { + LL_INFOS("WebSocket") << "Stopping server: " << name << LL_ENDL; + server->stop(); + } + } + + mServers.clear(); +} + +//------------------------------------------------------------------------ +struct Server_impl +{ + Server_impl(LLWebsocketMgr::WSServer *owner, U16 port, bool local_only) : + mOwner(owner), + mPort(port), + mLocalOnly(local_only) + { + + mServer.set_open_handler([this](websocketpp::connection_hdl hdl) { this->onOpen(hdl); }); + mServer.set_close_handler([this](websocketpp::connection_hdl hdl) { this->onClose(hdl); }); + mServer.set_message_handler([this](websocketpp::connection_hdl hdl, Server_t::message_ptr msg) { this->onMessage(hdl, msg); }); + } + + ~Server_impl() = default; + + /** + * @brief Initialize the websocketpp server and configure listening + * + * Performs the initial setup of the websocketpp server by calling init_asio() + * to initialize the ASIO networking layer, then configures the server to listen + * on the specified port. The binding behavior depends on the mLocalOnly flag: + * - If mLocalOnly is true: binds to "127.0.0.1" (localhost only) + * - If mLocalOnly is false: binds to all available network interfaces + */ + void init() + { + mServer.init_asio(); + if (mLocalOnly) + { + std::stringstream port_str; + port_str << mPort; + mServer.listen("127.0.0.1", port_str.str()); + } + else + { + mServer.listen(mPort); + } + } + + /** + * @brief Start the websocket server and begin accepting connections + * @return true if server started successfully, false on error + */ + bool start() + { + //if (!mServer.stopped()) + //{ + // LL_WARNS("WebSocket") << "WebSocket server is already running" << LL_ENDL; + // return false; + //} + + try + { + LL_INFOS("WebSocket") << "Starting WebSocket server on port " << mPort + << (mLocalOnly ? " (localhost only)" : " (all interfaces)") << LL_ENDL; + mServer.start_accept(); + + // Run controlled event loop with periodic stop flag checking + while (!mOwner->mShouldStop && !mServer.stopped()) + { + // Process events for up to 100ms, then check the stop flag + std::chrono::milliseconds timeout(100); + std::size_t handlers_run = mServer.get_io_service().run_for(timeout); + + // If no handlers were run and the server isn't stopped, + // reset the io_service for the next iteration + if (handlers_run == 0 && !mServer.stopped() && !mOwner->mShouldStop) + { + mServer.get_io_service().restart(); + } + } + + LL_INFOS("WebSocket") << "WebSocket server event loop exited cleanly" << LL_ENDL; + return true; + } + catch (const websocketpp::exception& e) + { + LL_WARNS("WebSocket") << "WebSocket server exception: " << e.what() << LL_ENDL; + return false; + } + catch (const std::exception& e) + { + LL_WARNS("WebSocket") << "WebSocket server std::exception: " << e.what() << LL_ENDL; + return false; + } + catch (...) + { + LL_WARNS("WebSocket") << "WebSocket server unknown exception" << LL_ENDL; + return false; + } + } + + void stop() + { + if (mServer.stopped()) + { + return; + } + try + { + mServer.stop_listening(); + mServer.stop(); + } + catch (const std::exception&) + { + LL_WARNS("WebSocket") << "Error stopping WebSocket server" << LL_ENDL; + } + } + + /** + * @brief Handle new connection establishment event + * @param hdl WebSocket connection handle from websocketpp + * + * Called automatically by the websocketpp library when a new client connection + * is successfully established. This method serves as a bridge between the + * low-level websocketpp callback and the high-level WSServer interface. + */ + void onOpen(websocketpp::connection_hdl hdl) const + { + LL_ERRS_IF(!mOwner, "WebSocket") << "mOwner should never be null. If it is, something is very wrong!" << LL_ENDL; + + mOwner->handleOpenConnection(hdl); + } + + /** + * @brief Handle connection closure event + * @param hdl WebSocket connection handle from websocketpp + */ + void onClose(websocketpp::connection_hdl hdl) const + { + LL_ERRS_IF(!mOwner, "WebSocket") << "mOwner should never be null" << LL_ENDL; + mOwner->handleCloseConnection(hdl); + } + + /** + * @brief Handle incoming message from client + * @param hdl WebSocket connection handle identifying the sender + * @param msg Shared pointer to the message object containing payload and metadata + * + * Called automatically by the websocketpp library when a complete message is + * received from a client. This method validates the connection exists, extracts + * the message payload, and forwards it to the appropriate connection handler. + * + * Currently handles text messages only. + */ + void onMessage(websocketpp::connection_hdl hdl, Server_t::message_ptr msg) const + { + LL_ERRS_IF(!mOwner, "WebSocket") << "mOwner should never be null" << LL_ENDL; + LLWebsocketMgr::WSConnection::ptr_t connection = mOwner->getConnection(hdl); + if (!connection) + { + LL_WARNS("WebSocket") << "Received message for unknown connection" << LL_ENDL; + return; + } + + // TODO: check the FIN bit and handle fragmented messages if needed + // TODO: check terminal and close codes and handle connection closure if needed + mOwner->handleMessage(hdl, msg->get_payload()); + } + + //------------------------------------------- + Server_t mServer; ///< The underlying websocketpp server instance + LLWebsocketMgr::WSServer* mOwner{ nullptr }; ///< Back-reference to the owning WSServer instance (guaranteed non-null) + U16 mPort{ 0 }; ///< TCP port number the server listens on + bool mLocalOnly{ true }; ///< Whether to bind to localhost only (true) or all interfaces (false) +}; + +//------------------------------------------------------------------------ +LLWebsocketMgr::WSServer::WSServer(std::string_view name, U16 port, bool local_only): + mServerName(name), + mImpl(std::make_unique(this, port, local_only)) +{ + mImpl->init(); + + // Initialize the server with the given name and host + LL_INFOS("WebSocket") << "Creating WebSocket server: " << name << + " listening " << (mImpl->mLocalOnly ? "locally" : "ON ALL INTERFACES") << + " on port " << mImpl->mPort << LL_ENDL; +} + +LLWebsocketMgr::WSServer::~WSServer() +{ + // Ensure the server is stopped before destruction + stop(); +} + +LLWebsocketMgr::WSConnection::ptr_t LLWebsocketMgr::WSServer::connectionFactory(LLWebsocketMgr::WSServer::ptr_t server, + LLWebsocketMgr::connection_h handle) +{ + return std::make_shared(server, handle); +} + +bool LLWebsocketMgr::WSServer::start() +{ + LL_ERRS_IF(!mImpl, "WebSocket") << "WebSocket server " << mServerName << " implementation is null !" << LL_ENDL; + + LLMutexLock lock(&mThreadMutex); + + // Check if already running + if (isRunning()) + { + LL_WARNS("WebSocket") << "Server " << mServerName << " is already running" << LL_ENDL; + return false; + } + + // Reset the stop flag + mShouldStop = false; + + // Start the server thread + mServerThread = std::thread([this]() { + LL_INFOS("WebSocket") << "WebSocket server thread starting for: " << mServerName << LL_ENDL; + + // Run the controlled server loop that checks the stop flag + // Server_impl accesses mShouldStop through the mOwner pointer + bool success = mImpl->start(); + + if (!success) + { + LL_WARNS("WebSocket") << "WebSocket server thread failed to start for: " << mServerName << LL_ENDL; + } + + LL_INFOS("WebSocket") << "WebSocket server thread exiting for: " << mServerName << LL_ENDL; + }); + + onStarted(); + LL_INFOS("WebSocket") << "Started WebSocket server thread: " << mServerName << LL_ENDL; + return true; +} + +void LLWebsocketMgr::WSServer::stop() +{ + LL_ERRS_IF(!mImpl, "WebSocket") << "WebSocket server " << mServerName << " implementation is null !" << LL_ENDL; + + { + LLMutexLock lock(&mThreadMutex); + + // Check if already stopped + if (!isRunning()) + { + return; + } + + LL_INFOS("WebSocket") << "Stopping WebSocket server: " << mServerName << LL_ENDL; + + mShouldStop = true; + + // Stop the websocket server (this will cause the controlled run loop to exit) + mImpl->stop(); + } // Release the lock here + + if (mServerThread.joinable()) + { + mServerThread.join(); + LL_INFOS("WebSocket") << "WebSocket server thread joined for: " << mServerName << LL_ENDL; + } + onStopped(); +} + +bool LLWebsocketMgr::WSServer::isRunning() const +{ + LL_ERRS_IF(!mImpl, "WebSocket") << "WebSocket server " << mServerName << " implementation is null !" << LL_ENDL; + + // Check both the thread state, websocket server state, and the stop flag + return mServerThread.joinable() && !mImpl->mServer.stopped() && !mShouldStop; +} + +void LLWebsocketMgr::WSServer::broadcastMessage(const std::string& message) +{ + LL_ERRS_IF(!mImpl, "WebSocket") << "WebSocket server " << mServerName << " implementation is null !" << LL_ENDL; + LLMutexLock lock(&mConnectionMutex); + for (const auto& [handle, conn] : mConnections) + { + sendMessageTo(handle, message); + } +} + +bool LLWebsocketMgr::WSServer::sendMessageTo(const connection_h& handle, const std::string& message) +{ + LL_ERRS_IF(!mImpl, "WebSocket") << "WebSocket server " << mServerName << " implementation is null !" << LL_ENDL; + websocketpp::lib::error_code ec; + mImpl->mServer.send(handle, message, websocketpp::frame::opcode::text, ec); + if (ec) + { + LL_WARNS("WebSocket") << mServerName << " failed to send message: " << ec.message() << LL_ENDL; + return false; + } + return true; +} + +bool LLWebsocketMgr::WSServer::closeConnection(const connection_h& handle, U16 code, const std::string& reason) +{ + LL_ERRS_IF(!mImpl, "WebSocket") << "WebSocket server " << mServerName << " implementation is null !" << LL_ENDL; + + try + { + websocketpp::lib::error_code ec; + mImpl->mServer.close(handle, code, reason, ec); + if (ec) + { + LL_WARNS("WebSocket") << mServerName << " failed to close connection: " << ec.message() << LL_ENDL; + return false; + } + + LL_INFOS("WebSocket") << mServerName << " initiated close for connection with code " + << code << " and reason: " << reason << LL_ENDL; + return true; + } + catch (const websocketpp::exception& e) + { + LL_WARNS("WebSocket") << mServerName << " exception closing connection: " << e.what() << LL_ENDL; + return false; + } + catch (const std::exception& e) + { + LL_WARNS("WebSocket") << mServerName << " std::exception closing connection: " << e.what() << LL_ENDL; + return false; + } + catch (...) + { + LL_WARNS("WebSocket") << mServerName << " unknown exception closing connection" << LL_ENDL; + return false; + } +} + +LLWebsocketMgr::WSConnection::ptr_t LLWebsocketMgr::WSServer::getConnection(const connection_h& handle) +{ + LLMutexLock lock(&mConnectionMutex); + auto it = mConnections.find(handle); + if (it != mConnections.end()) + { + return it->second; + } + return nullptr; +} + +LLWebsocketMgr::connection_state_t LLWebsocketMgr::WSServer::getConnectionState(const connection_h& handle) const +{ + websocketpp::lib::error_code ec; + auto con = mImpl->mServer.get_con_from_hdl(handle, ec); + if (ec) + { + LL_WARNS("WebSocket") << mServerName << " failed to get connection state: " << ec.message() << LL_ENDL; + websocketpp::session::state::value state = websocketpp::session::state::closed; + return connection_closed; + } + return static_cast(con->get_state()); +} + + +void LLWebsocketMgr::WSServer::handleOpenConnection(const connection_h& handle) +{ + WSConnection::ptr_t connection; + size_t size(0); + { + LLMutexLock lock(&mConnectionMutex); + auto it = mConnections.find(handle); + if (it == mConnections.end()) + { + connection = connectionFactory(shared_from_this(), handle); + if (!connection) + { + LL_WARNS("WebSocket") << "Failed to create connection for websocket server " << mServerName << LL_ENDL; + return; + } + mConnections[handle] = connection; + } + else + { + connection = it->second; + } + + if (!connection) + { + LL_WARNS("WebSocket") << mServerName << " failed to create connection object" << LL_ENDL; + return; + } + // Removed redundant assignment to mConnections[handle] + size = mConnections.size(); + } + + onConnectionOpened(connection); // TODO: consider letting the server reject the connection here + connection->onOpen(); + LL_INFOS("WebSocket") << mServerName << " opened new connection, total connections: " << size << LL_ENDL; +} + +void LLWebsocketMgr::WSServer::handleCloseConnection(const connection_h& handle) +{ + size_t size(0); + WSConnection::ptr_t connection; + { + LLMutexLock lock(&mConnectionMutex); + auto it = mConnections.find(handle); + if (it != mConnections.end()) + { + connection = it->second; + mConnections.erase(it); + } + size = mConnections.size(); + } + if (connection) + { + connection->onClose(); + onConnectionClosed(connection); + LL_INFOS("WebSocket") << mServerName << " closed connection, total connections: " << size << LL_ENDL; + } + else + { + LL_WARNS("WebSocket") << mServerName << " attempted to close unknown connection" << LL_ENDL; + } +} + +void LLWebsocketMgr::WSServer::handleMessage(const connection_h& handle, const std::string& message) +{ + WSConnection::ptr_t connection = getConnection(handle); + if (connection) + { + connection->onMessage(message); + } + else + { + LL_WARNS("WebSocket") << mServerName << " received message for unknown connection" << LL_ENDL; + } +} + +//------------------------------------------------------------------------ +bool LLWebsocketMgr::WSConnection::sendMessage(const std::string& message) const +{ + if (mOwningServer.expired()) + { + LL_WARNS("WebSocket") << "Attempted to send message on connection with null server reference" << LL_ENDL; + return false; + } + return mOwningServer.lock()->sendMessageTo(mConnectionHandle, message); +} + +bool LLWebsocketMgr::WSConnection::sendMessage(const boost::json::value& json) const +{ + std::string message = boost::json::serialize(json); + return sendMessage(message); +} + +bool LLWebsocketMgr::WSConnection::sendMessage(const LLSD& data) const +{ + return sendMessage(LlsdToJson(data)); +} + +void LLWebsocketMgr::WSConnection::closeConnection(U16 code, const std::string& reason) +{ + if (mOwningServer.expired()) + { + LL_WARNS("WebSocket") << "Attempted to close connection with null server reference" << LL_ENDL; + return; + } + + LL_INFOS("WebSocket") << "WSConnection closing connection with code " << code + << " and reason: " << (reason.empty() ? "(no reason)" : reason) << LL_ENDL; + + if (!mOwningServer.lock()->closeConnection(mConnectionHandle, code, reason)) + { + LL_WARNS("WebSocket") << "Failed to close connection through server" << LL_ENDL; + } +} + +bool LLWebsocketMgr::WSConnection::isConnected() const +{ + if (mOwningServer.expired()) + { + return false; + } + + LLWebsocketMgr::WSServer::ptr_t server = mOwningServer.lock(); + if (!server) + { + return false; + } + return server->getConnectionState(mConnectionHandle) == connection_open; +} diff --git a/indra/llcorehttp/llwebsocketmgr.h b/indra/llcorehttp/llwebsocketmgr.h new file mode 100644 index 00000000000..4165b3cecc4 --- /dev/null +++ b/indra/llcorehttp/llwebsocketmgr.h @@ -0,0 +1,305 @@ +/** + * @file llwebsocketmgr.h + * @brief WebSocket manager singleton for managing WebSocket servers and connections + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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$ + */ + +#pragma once + +#include "llsingleton.h" +#include "llsd.h" +#include "lluuid.h" +#include "llhost.h" +#include "llmutex.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +struct Server_impl; + +/** + * @class LLWebsocketMgr + * @brief Singleton manager for WebSocket connections and servers + * + * This class provides a high-level interface for managing WebSocket connections + * and servers using websocketpp library. It handles both client and server + * connections, provides thread-safe operations, and integrates with the + * existing Linden Lab infrastructure. + */ +class LLWebsocketMgr: public LLSingleton +{ + LLSINGLETON(LLWebsocketMgr) = default; + virtual ~LLWebsocketMgr() = default; + LOG_CLASS(LLWebsocketMgr); + +public: + using connection_h = websocketpp::connection_hdl; + class WSServer; + + enum connection_state_t + { // must map to websocketpp::session::state + connection_connecting = 0, + connection_open = 1, + connection_closing = 2, + connection_closed = 3 + }; + + class WSConnection + { + friend class LLWebsocketMgr; + + public: + using ptr_t = std::shared_ptr; + + /** + * @brief Constructor for WSConnection + * @param server Shared pointer to the parent WSServer + * @param handle WebSocket connection handle from websocketpp + */ + WSConnection(const std::shared_ptr &server, const connection_h& handle): + mConnectionHandle(handle), + mOwningServer(server) + {} + + virtual ~WSConnection() = default; + + /** + * Override this method in derived classes to handle connection establishment. + * This is called after the WebSocket handshake is complete and the connection + * is ready to send/receive messages. + */ + virtual void onOpen() {} + + /** + * Override this method in derived classes to handle connection closure. + * This is called when the connection has been terminated, either normally + * or due to an error condition. + */ + virtual void onClose() {} + + /** + * @brief Called when a message is received + * @param message The received message as a string + * + * Override this method in derived classes to handle incoming messages. + * Currently only text messages are supported. + */ + virtual void onMessage(const std::string& message) {} + + /** + * @brief Send a message to the connected client + * @param message The message string to send + * @return true if the message was queued successfully, false on error + * + * Sends a text message to the remote endpoint. The message is queued + * asynchronously and may not be sent immediately. + */ + bool sendMessage(const std::string& message) const; + bool sendMessage(const boost::json::value& json) const; + bool sendMessage(const LLSD& data) const; + + /** + * @brief Close the WebSocket connection gracefully + * @param code Optional close code (default: normal closure) + * @param reason Optional reason string (default: empty) + * + * Initiates a graceful WebSocket close handshake. The connection will + * send a close frame with the specified code and reason, then wait for + * the remote endpoint to respond with its own close frame before + * actually closing the underlying TCP connection. + * + * Common close codes: + * - 1000: Normal closure (default) + * - 1001: Going away (server shutting down, page navigating away) + * - 1002: Protocol error + * - 1003: Unsupported data type + * - 1008: Policy violation + * - 1009: Message too big + * + * @note After calling this method, no further messages should be sent + * @note The onClose() callback will be invoked when the close handshake completes + */ + void closeConnection(U16 code = 1000, const std::string& reason = std::string()); + + bool isConnected() const; + + protected: + connection_h mConnectionHandle; + std::weak_ptr mOwningServer; // Back-reference to the server this connection belongs to + }; + + /** + * @class WSServer + * @brief Base class for WebSocket servers with customizable connection handling + * + * WSServer provides a high-level abstraction over websocketpp servers, handling + * threading, connection management, and event dispatching. Derive from this class + * to create custom WebSocket servers with application-specific logic. + * + * ## Basic Usage + * + * @code + * class MyServer : public LLWebsocketMgr::WSServer + * { + * public: + * MyServer(const std::string& name, U16 port) + * : WSServer(name, port, false) // Listen on all interfaces + * {} + * + * void onConnectionOpened(const WSConnection::ptr_t& connection) override + * { + * LL_INFOS("MyServer") << "New client connected" << LL_ENDL; + * // Send welcome message + * connection->sendMessage("Welcome to the server!"); + * } + * + * void onConnectionClosed(const WSConnection::ptr_t& connection) override + * { + * LL_INFOS("MyServer") << "Client disconnected" << LL_ENDL; + * } + * + * protected: + * // Use custom connection class + * WSConnection::ptr_t connectionFactory(WSServer::ptr_t server, connection_h handle) override + * { + * return std::make_shared(server, handle); + * } + * }; + * @endcode + * + * ## Connection Management + * + * The server automatically manages connection lifetimes and provides several ways + * to interact with connections: + * + * - `broadcastMessage()` - Send message to all connected clients + * - `sendMessageTo()` - Send message to specific connection + * - `closeConnection()` - Close specific connection with code/reason + * - `getConnection()` - Get connection object by handle + * + * ## Thread Safety + * + * All public methods are thread-safe and can be called from any thread. The server + * runs its own background thread for handling WebSocket events, while connection + * callbacks are also executed on this background thread. + */ + class WSServer: public std::enable_shared_from_this + { + friend struct Server_impl; + friend class WSConnection; + friend class LLWebsocketMgr; + + public: + using ptr_t = std::shared_ptr; + + WSServer(std::string_view name, U16 port, bool local_only = true); + virtual ~WSServer(); + + virtual void onStarted() {} + virtual void onStopped() {} + + virtual void onConnectionOpened(const WSConnection::ptr_t& connection) { } + virtual void onConnectionClosed(const WSConnection::ptr_t& connection) { } + + bool isRunning() const; + size_t getConnectionCount() const + { + LLMutexLock lock(&mConnectionMutex); + return mConnections.size(); + } + + void broadcastMessage(const std::string& message); + virtual bool update() { return true; } + + connection_state_t getConnectionState(const connection_h& handle) const; + + protected: + virtual WSConnection::ptr_t connectionFactory(WSServer::ptr_t server, connection_h handle); + + bool start(); + void stop(); + + bool sendMessageTo(const connection_h& handle, const std::string& message); + + /** + * @brief Close a specific connection gracefully + * @param handle The connection handle to close + * @param code Close code (default: normal closure) + * @param reason Close reason string (default: empty) + * @return true if close was initiated successfully, false on error + * + * Internal method used by WSConnection to close individual connections. + * This method is thread-safe and can be called from any thread. + */ + bool closeConnection(const connection_h& handle, U16 code = 1000, const std::string& reason = std::string()); + + private: + using connection_map_t = std::map >; + + WSConnection::ptr_t getConnection(const connection_h& handle); + + void handleOpenConnection(const connection_h& handle); + void handleCloseConnection(const connection_h& handle); + void handleMessage(const connection_h& handle, const std::string& message); + + std::string mServerName; + std::unique_ptr mImpl; + connection_map_t mConnections; + mutable LLMutex mConnectionMutex; + + // Threading support + std::thread mServerThread; ///< Thread running the ASIO event loop + std::atomic mShouldStop{ false }; ///< Thread-safe stop flag + mutable LLMutex mThreadMutex; ///< Mutex for thread synchronization + }; + + // Server and Connection Management + WSServer::ptr_t findServerByName(const std::string &name) const; + + bool addServer(const WSServer::ptr_t& server); + bool removeServer(const std::string &name); + + bool startServer(const std::string &name) const; + void stopServer(const std::string &name) const; + + void update(); + +protected: + void initSingleton() override; + void cleanupSingleton() override; + +private: + using server_map_t = std::map; + + void stopAllServers(); + + server_map_t mServers; +}; diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp index c0cc2c80301..c7c50e61664 100755 --- a/indra/llcorehttp/tests/llcorehttp_test.cpp +++ b/indra/llcorehttp/tests/llcorehttp_test.cpp @@ -41,11 +41,7 @@ #include "test_httpstatus.hpp" #include "test_refcounted.hpp" #include "test_httpoperation.hpp" -// As of 2019-06-28, test_httprequest.hpp consistently crashes on Mac Release -// builds for reasons not yet diagnosed. -#if ! (LL_DARWIN && LL_RELEASE) #include "test_httprequest.hpp" -#endif #include "test_httpheaders.hpp" #include "test_httprequestqueue.hpp" #include "_httpservice.h" @@ -53,9 +49,6 @@ #include "llproxy.h" #include "llcleanup.h" -void ssl_thread_id_callback(CRYPTO_THREADID*); -void ssl_locking_callback(int mode, int type, const char * file, int line); - #if 0 // lltut provides main and runner namespace tut @@ -80,27 +73,10 @@ int main() #endif // 0 -int ssl_mutex_count(0); -LLCoreInt::HttpMutex ** ssl_mutex_list = NULL; - void init_curl() { curl_global_init(CURL_GLOBAL_ALL); - ssl_mutex_count = CRYPTO_num_locks(); - if (ssl_mutex_count > 0) - { - ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count]; - - for (int i(0); i < ssl_mutex_count; ++i) - { - ssl_mutex_list[i] = new LLCoreInt::HttpMutex; - } - - CRYPTO_set_locking_callback(ssl_locking_callback); - CRYPTO_THREADID_set_callback(ssl_thread_id_callback); - } - LLProxy::getInstance(); } @@ -108,39 +84,6 @@ void init_curl() void term_curl() { SUBSYSTEM_CLEANUP(LLProxy); - - CRYPTO_set_locking_callback(NULL); - for (int i(0); i < ssl_mutex_count; ++i) - { - delete ssl_mutex_list[i]; - } - delete [] ssl_mutex_list; -} - - -void ssl_thread_id_callback(CRYPTO_THREADID* pthreadid) -{ -#if defined(WIN32) - CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread()); -#else - CRYPTO_THREADID_set_pointer(pthreadid, pthread_self()); -#endif -} - - -void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */) -{ - if (type >= 0 && type < ssl_mutex_count) - { - if (mode & CRYPTO_LOCK) - { - ssl_mutex_list[type]->lock(); - } - else - { - ssl_mutex_list[type]->unlock(); - } - } } diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index aed906bb8fa..77ed8df066a 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -454,6 +454,10 @@ void HttpRequestTestObjectType::test<4>() template <> template <> void HttpRequestTestObjectType::test<5>() { +#ifndef LL_WINDOWS + skip("Skip due to issues with testing pthread cancellation"); +#endif + ScopedCurlInit ready; set_test_name("HttpRequest Spin (soft) + NoOp + hard termination"); @@ -517,6 +521,9 @@ void HttpRequestTestObjectType::test<5>() template <> template <> void HttpRequestTestObjectType::test<6>() { +#ifndef LL_WINDOWS + skip("Skip due to issues with testing pthread cancellation"); +#endif ScopedCurlInit ready; set_test_name("HttpRequest Spin + NoOp + hard termination"); @@ -2779,7 +2786,7 @@ void HttpRequestTestObjectType::test<22>() for (int i(0); i < test_count; ++i) { char buffer[128]; - sprintf(buffer, "/bug2295/%d/", i); + snprintf(buffer, sizeof(buffer), "/bug2295/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, url_base + buffer, 0, @@ -2810,7 +2817,7 @@ void HttpRequestTestObjectType::test<22>() for (int i(0); i < test2_count; ++i) { char buffer[128]; - sprintf(buffer, "/bug2295/00000012/%d/", i); + snprintf(buffer, sizeof(buffer), "/bug2295/00000012/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, url_base + buffer, 0, @@ -2841,7 +2848,7 @@ void HttpRequestTestObjectType::test<22>() for (int i(0); i < test3_count; ++i) { char buffer[128]; - sprintf(buffer, "/bug2295/inv_cont_range/%d/", i); + snprintf(buffer, sizeof(buffer), "/bug2295/inv_cont_range/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, url_base + buffer, 0, diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/test_refcounted.hpp index c0c8e784130..eb23a25545a 100644 --- a/indra/llcorehttp/tests/test_refcounted.hpp +++ b/indra/llcorehttp/tests/test_refcounted.hpp @@ -28,8 +28,6 @@ #include "_refcounted.h" -// disable all of this because it's hanging win64 builds? -#if ! (LL_WINDOWS && ADDRESS_SIZE == 64) using namespace LLCoreInt; namespace tut @@ -122,5 +120,4 @@ namespace tut ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED); } } -#endif // disabling on Win64 #endif // TEST_LLCOREINT_REF_COUNTED_H_ diff --git a/indra/llcrashlogger/llcrashlock.cpp b/indra/llcrashlogger/llcrashlock.cpp index ecd197b2c13..bc34f6798fd 100644 --- a/indra/llcrashlogger/llcrashlock.cpp +++ b/indra/llcrashlogger/llcrashlock.cpp @@ -189,7 +189,7 @@ LLSD LLCrashLock::getProcessList() bool LLCrashLock::fileExists(std::string filename) { #ifdef LL_WINDOWS // or BOOST_WINDOWS_API - boost::filesystem::path file_path(utf8str_to_utf16str(filename)); + boost::filesystem::path file_path(ll_convert(filename)); #else boost::filesystem::path file_path(filename); #endif @@ -199,7 +199,7 @@ bool LLCrashLock::fileExists(std::string filename) void LLCrashLock::cleanupProcess(std::string proc_dir) { #ifdef LL_WINDOWS // or BOOST_WINDOWS_API - boost::filesystem::path dir_path(utf8str_to_utf16str(proc_dir)); + boost::filesystem::path dir_path(ll_convert(proc_dir)); #else boost::filesystem::path dir_path(proc_dir); #endif diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp index b80243c22e5..ea33a3bb906 100644 --- a/indra/llfilesystem/lldir.cpp +++ b/indra/llfilesystem/lldir.cpp @@ -103,7 +103,7 @@ std::vector LLDir::getFilesInDir(const std::string &dirname) //Returns a vector of fullpath filenames. #ifdef LL_WINDOWS // or BOOST_WINDOWS_API - boost::filesystem::path p(utf8str_to_utf16str(dirname)); + boost::filesystem::path p(ll_convert(dirname)); #else boost::filesystem::path p(dirname); #endif @@ -197,7 +197,7 @@ U32 LLDir::deleteDirAndContents(const std::string& dir_name) try { #ifdef LL_WINDOWS // or BOOST_WINDOWS_API - boost::filesystem::path dir_path(utf8str_to_utf16str(dir_name)); + boost::filesystem::path dir_path(ll_convert(dir_name)); #else boost::filesystem::path dir_path(dir_name); #endif diff --git a/indra/llfilesystem/lldir_mac.cpp b/indra/llfilesystem/lldir_mac.cpp index b9be75c528f..2db1b6ec5d4 100644 --- a/indra/llfilesystem/lldir_mac.cpp +++ b/indra/llfilesystem/lldir_mac.cpp @@ -149,7 +149,7 @@ LLDir_Mac::LLDir_Mac() mWorkingDir = getCurPath(); - mLLPluginDir = mAppRODataDir + mDirDelimiter + "llplugin"; + mLLPluginDir = mAppRODataDir + mDirDelimiter + "SLPlugin.app" + mDirDelimiter + "Contents" + mDirDelimiter + "Frameworks"; } } diff --git a/indra/llfilesystem/lldir_win32.cpp b/indra/llfilesystem/lldir_win32.cpp index a607c70b449..58c080c9823 100644 --- a/indra/llfilesystem/lldir_win32.cpp +++ b/indra/llfilesystem/lldir_win32.cpp @@ -172,7 +172,7 @@ LLDir_Win32::LLDir_Win32() { w_str[wcslen(w_str)-1] = '\0'; /* Flawfinder: ignore */ // remove trailing slash } - mTempDir = utf16str_to_utf8str(llutf16string(w_str)); + mTempDir = ll_convert(std::wstring(w_str)); if (mOSUserDir.empty()) { @@ -225,14 +225,14 @@ LLDir_Win32::LLDir_Win32() // Set working directory, for LLDir::getWorkingDir() GetCurrentDirectory(MAX_PATH, w_str); - mWorkingDir = utf16str_to_utf8str(llutf16string(w_str)); + mWorkingDir = ll_convert(std::wstring(w_str)); // Set the executable directory S32 size = GetModuleFileName(NULL, w_str, MAX_PATH); if (size) { w_str[size] = '\0'; - mExecutablePathAndName = utf16str_to_utf8str(llutf16string(w_str)); + mExecutablePathAndName = ll_convert(std::wstring(w_str)); auto path_end = mExecutablePathAndName.find_last_of('\\'); if (path_end != std::string::npos) { @@ -347,8 +347,8 @@ U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string & WIN32_FIND_DATA FileData; - llutf16string pathname = utf8str_to_utf16str(dirname); - pathname += utf8str_to_utf16str(mask); + std::wstring pathname = ll_convert(dirname); + pathname += ll_convert(mask); if ((count_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE) { @@ -370,7 +370,7 @@ std::string LLDir_Win32::getCurPath() WCHAR w_str[MAX_PATH]; GetCurrentDirectory(MAX_PATH, w_str); - return utf16str_to_utf8str(llutf16string(w_str)); + return ll_convert(std::wstring(w_str)); } diff --git a/indra/llfilesystem/lldir_win32.h b/indra/llfilesystem/lldir_win32.h index ab2726f1a04..21a3f1213b2 100644 --- a/indra/llfilesystem/lldir_win32.h +++ b/indra/llfilesystem/lldir_win32.h @@ -51,7 +51,7 @@ class LLDir_Win32 : public LLDir private: void* mDirSearch_h{ nullptr }; - llutf16string mCurrentDir; + std::wstring mCurrentDir; }; #endif // LL_LLDIR_WIN32_H diff --git a/indra/llfilesystem/lldirguard.h b/indra/llfilesystem/lldirguard.h index fcb179bbc80..c6ce13efb49 100644 --- a/indra/llfilesystem/lldirguard.h +++ b/indra/llfilesystem/lldirguard.h @@ -31,6 +31,9 @@ #include "llerror.h" #if LL_WINDOWS + +#include "llwin32headers.h" + class LLDirectoryGuard { public: @@ -46,8 +49,8 @@ class LLDirectoryGuard (wcsncmp(mOrigDir,mFinalDir,mOrigDirLen)!=0)) { // Dir has changed - std::string mOrigDirUtf8 = utf16str_to_utf8str(llutf16string(mOrigDir)); - std::string mFinalDirUtf8 = utf16str_to_utf8str(llutf16string(mFinalDir)); + std::string mOrigDirUtf8 = ll_convert(std::wstring(mOrigDir)); + std::string mFinalDirUtf8 = ll_convert(std::wstring(mFinalDir)); LL_INFOS() << "Resetting working dir from " << mFinalDirUtf8 << " to " << mOrigDirUtf8 << LL_ENDL; SetCurrentDirectory(mOrigDir); } diff --git a/indra/llfilesystem/lldiriterator.cpp b/indra/llfilesystem/lldiriterator.cpp index 61f768c512d..e8c37389d2a 100644 --- a/indra/llfilesystem/lldiriterator.cpp +++ b/indra/llfilesystem/lldiriterator.cpp @@ -52,7 +52,7 @@ LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask) : mIsValid(false) { #ifdef LL_WINDOWS // or BOOST_WINDOWS_API - fs::path dir_path(utf8str_to_utf16str(dirname)); + fs::path dir_path(ll_convert(dirname)); #else fs::path dir_path(dirname); #endif diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index 49904911a91..e971e1885a2 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -103,7 +103,7 @@ void LLDiskCache::purge() std::vector file_info; #if LL_WINDOWS - std::wstring cache_path(utf8str_to_utf16str(sCacheDir)); + std::wstring cache_path(ll_convert(sCacheDir)); #else std::string cache_path(sCacheDir); #endif @@ -226,7 +226,7 @@ void LLDiskCache::clearCache() */ boost::system::error_code ec; #if LL_WINDOWS - std::wstring cache_path(utf8str_to_utf16str(sCacheDir)); + std::wstring cache_path(ll_convert(sCacheDir)); #else std::string cache_path(sCacheDir); #endif @@ -259,7 +259,7 @@ void LLDiskCache::removeOldVFSFiles() boost::system::error_code ec; #if LL_WINDOWS - std::wstring cache_path(utf8str_to_utf16str(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""))); + std::wstring cache_path(ll_convert(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""))); #else std::string cache_path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "")); #endif @@ -300,7 +300,7 @@ uintmax_t LLDiskCache::dirFileSize(const std::string& dir) */ boost::system::error_code ec; #if LL_WINDOWS - std::wstring dir_path(utf8str_to_utf16str(dir)); + std::wstring dir_path(ll_convert(dir)); #else std::string dir_path(dir); #endif diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index c8ce9531c28..5ce5244107d 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -316,7 +316,7 @@ void LLFileSystem::updateFileAccessTime(const std::string& file_path) boost::system::error_code ec; #if LL_WINDOWS // file last write time - const std::time_t last_write_time = boost::filesystem::last_write_time(utf8str_to_utf16str(file_path), ec); + const std::time_t last_write_time = boost::filesystem::last_write_time(ll_convert(file_path), ec); if (ec.failed()) { LL_WARNS() << "Failed to read last write time for cache file " << file_path << ": " << ec.message() << LL_ENDL; @@ -330,7 +330,7 @@ void LLFileSystem::updateFileAccessTime(const std::string& file_path) // before the last one if (delta_time > time_threshold) { - boost::filesystem::last_write_time(utf8str_to_utf16str(file_path), cur_time, ec); + boost::filesystem::last_write_time(ll_convert(file_path), cur_time, ec); } #else // file last write time diff --git a/indra/llfilesystem/tests/lldir_test.cpp b/indra/llfilesystem/tests/lldir_test.cpp index 6e191ad096d..d7d57fa86fb 100644 --- a/indra/llfilesystem/tests/lldir_test.cpp +++ b/indra/llfilesystem/tests/lldir_test.cpp @@ -435,7 +435,7 @@ namespace tut for (counter=0, foundUnused=false; !foundUnused; counter++ ) { char counterStr[3]; - sprintf(counterStr, "%02d", counter); + snprintf(counterStr, sizeof(counterStr), "%02d", counter); uniqueDir = dirbase + counterStr; foundUnused = ! ( LLFile::isdir(uniqueDir) || LLFile::isfile(uniqueDir) ); } diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index effd33b410a..ab6c593fc2d 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -31,7 +31,9 @@ #include "llerror.h" #include "llexception.h" +#if !LL_ARM64 jmp_buf LLImageJPEG::sSetjmpBuffer ; +#endif LLImageJPEG::LLImageJPEG(S32 quality) : LLImageFormatted(IMG_CODEC_JPEG), mOutputBuffer( NULL ), @@ -78,12 +80,15 @@ bool LLImageJPEG::updateData() // //try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error //so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao + //except in the case of AARCH64/ARM64 where setjmp will crash // +#if !LL_ARM64 if(setjmp(sSetjmpBuffer)) { jpeg_destroy_decompress(&cinfo); return false; } +#endif try { // Now we can initialize the JPEG decompression object. @@ -223,11 +228,13 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) //try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error //so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao // +#if !LL_ARM64 if(setjmp(sSetjmpBuffer)) { jpeg_destroy_decompress(&cinfo); return true; // done } +#endif try { // Now we can initialize the JPEG decompression object. @@ -431,9 +438,10 @@ void LLImageJPEG::errorExit( j_common_ptr cinfo ) // Let the memory manager delete any temp files jpeg_destroy(cinfo); - +#if !LL_ARM64 // Return control to the setjmp point longjmp(sSetjmpBuffer, 1) ; +#endif } // Decide whether to emit a trace or warning message. @@ -551,6 +559,7 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) //try/catch will crash on Mac and Linux if LLImageJPEG::errorExit throws an error //so as instead, we use setjmp/longjmp to avoid this crash, which is the best we can get. --bao // +#if !LL_ARM64 if( setjmp(sSetjmpBuffer) ) { // If we get here, the JPEG code has signaled an error. @@ -561,7 +570,7 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) mOutputBufferSize = 0; return false; } - +#endif try { diff --git a/indra/llimage/llimagejpeg.h b/indra/llimage/llimagejpeg.h index 012b87a42dd..ee0a8815e8d 100644 --- a/indra/llimage/llimagejpeg.h +++ b/indra/llimage/llimagejpeg.h @@ -78,7 +78,9 @@ class LLImageJPEG : public LLImageFormatted S32 mEncodeQuality; // on a scale from 1 to 100 private: +#if !LL_ARM64 static jmp_buf sSetjmpBuffer; // To allow the library to abort. +#endif }; #endif // LL_LLIMAGEJPEG_H diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 431f5aa0016..7cfadb889dd 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -29,8 +29,6 @@ // this is defined so that we get static linking. #include "openjpeg.h" -#include "event.h" -#include "cio.h" // Factory function: see declaration in llimagej2c.cpp LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl() @@ -48,6 +46,7 @@ std::string LLImageJ2COJ::getEngineInfo() const #endif } +#if WANT_VERBOSE_OPJ_SPAM // Return string from message, eliminating final \n if present static std::string chomp(const char* msg) { @@ -63,27 +62,34 @@ static std::string chomp(const char* msg) } return message; } +#endif /** sample error callback expecting a LLFILE* client object */ void error_callback(const char* msg, void*) { - LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; +#if WANT_VERBOSE_OPJ_SPAM + LL_WARNS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; +#endif } /** sample warning callback expecting a LLFILE* client object */ void warning_callback(const char* msg, void*) { - LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; +#if WANT_VERBOSE_OPJ_SPAM + LL_WARNS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; +#endif } /** sample debug callback expecting no client object */ void info_callback(const char* msg, void*) { - LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; +#if WANT_VERBOSE_OPJ_SPAM + LL_INFOS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; +#endif } // Divide a by 2 to the power of b and round upwards @@ -95,39 +101,13 @@ int ceildivpow2(int a, int b) class JPEG2KBase { public: - JPEG2KBase() {} + JPEG2KBase() = default; U8* buffer = nullptr; OPJ_SIZE_T size = 0; OPJ_OFF_T offset = 0; }; -#define WANT_VERBOSE_OPJ_SPAM LL_DEBUG - -static void opj_info(const char* msg, void* user_data) -{ - llassert(user_data); -#if WANT_VERBOSE_OPJ_SPAM - LL_INFOS("OpenJPEG") << msg << LL_ENDL; -#endif -} - -static void opj_warn(const char* msg, void* user_data) -{ - llassert(user_data); -#if WANT_VERBOSE_OPJ_SPAM - LL_WARNS("OpenJPEG") << msg << LL_ENDL; -#endif -} - -static void opj_error(const char* msg, void* user_data) -{ - llassert(user_data); -#if WANT_VERBOSE_OPJ_SPAM - LL_WARNS("OpenJPEG") << msg << LL_ENDL; -#endif -} - static OPJ_SIZE_T opj_read(void * buffer, OPJ_SIZE_T bytes, void* user_data) { llassert(user_data && buffer); @@ -283,11 +263,7 @@ class JPEG2KDecode : public JPEG2KBase JPEG2KDecode(S8 discardLevel) { - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); memset(¶meters, 0, sizeof(opj_dparameters_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; opj_set_default_decoder_parameters(¶meters); parameters.cp_reduce = discardLevel; } @@ -331,6 +307,11 @@ class JPEG2KDecode : public JPEG2KBase decoder = opj_create_decompress(OPJ_CODEC_J2K); + /* catch events using our callbacks and give a local context */ + opj_set_error_handler(decoder, error_callback, nullptr); + opj_set_warning_handler(decoder, warning_callback, nullptr); + opj_set_info_handler(decoder, info_callback, nullptr); + if (!opj_setup_decoder(decoder, ¶meters)) { return false; @@ -401,9 +382,9 @@ class JPEG2KDecode : public JPEG2KBase decoder = opj_create_decompress(OPJ_CODEC_J2K); opj_setup_decoder(decoder, ¶meters); - opj_set_info_handler(decoder, opj_info, this); - opj_set_warning_handler(decoder, opj_warn, this); - opj_set_error_handler(decoder, opj_error, this); + opj_set_info_handler(decoder, info_callback, this); + opj_set_warning_handler(decoder, warning_callback, this); + opj_set_error_handler(decoder, error_callback, this); if (stream) { @@ -469,7 +450,6 @@ class JPEG2KDecode : public JPEG2KBase private: opj_dparameters_t parameters; - opj_event_mgr_t event_mgr; opj_image_t* image = nullptr; opj_codec_t* decoder = nullptr; opj_stream_t* stream = nullptr; @@ -484,10 +464,6 @@ class JPEG2KEncode : public JPEG2KBase JPEG2KEncode(const char* comment_text_in, bool reversible) { memset(¶meters, 0, sizeof(opj_cparameters_t)); - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; opj_set_default_encoder_parameters(¶meters); parameters.cod_format = OPJ_CODEC_J2K; @@ -555,6 +531,11 @@ class JPEG2KEncode : public JPEG2KBase encoder = opj_create_compress(OPJ_CODEC_J2K); + /* catch events using our callbacks and give a local context */ + opj_set_error_handler(encoder, error_callback, nullptr); + opj_set_warning_handler(encoder, warning_callback, nullptr); + opj_set_info_handler(encoder, info_callback, nullptr); + parameters.tcp_mct = (image->numcomps >= 3) ? 1 : 0; // no color transform for RGBA images @@ -573,15 +554,6 @@ class JPEG2KEncode : public JPEG2KBase } - if (!opj_setup_encoder(encoder, ¶meters, image)) - { - return false; - } - - opj_set_info_handler(encoder, opj_info, this); - opj_set_warning_handler(encoder, opj_warn, this); - opj_set_error_handler(encoder, opj_error, this); - U32 width_tiles = (rawImageIn.getWidth() >> 6); U32 height_tiles = (rawImageIn.getHeight() >> 6); @@ -595,6 +567,19 @@ class JPEG2KEncode : public JPEG2KBase height_tiles = 1; } + if (width_tiles == 1 || height_tiles == 1) + { + // Images with either dimension less than 32 need less number of resolutions otherwise they error + int min_dim = rawImageIn.getWidth() < rawImageIn.getHeight() ? rawImageIn.getWidth() : rawImageIn.getHeight(); + int max_res = 1 + (int)floor(log2(min_dim)); + parameters.numresolution = max_res; + } + + if (!opj_setup_encoder(encoder, ¶meters, image)) + { + return false; + } + U32 tile_count = width_tiles * height_tiles; U32 data_size_guess = tile_count * TILE_SIZE; @@ -786,7 +771,6 @@ class JPEG2KEncode : public JPEG2KBase private: opj_cparameters_t parameters; - opj_event_mgr_t event_mgr; opj_image_t* image = nullptr; opj_codec_t* encoder = nullptr; opj_stream_t* stream = nullptr; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index ebf7445c65c..b17e22e4650 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -774,6 +774,7 @@ void LLPermissions::importLLSD(const LLSD& sd_perm) } } + fixOwnership(); fix(); } diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index 7cd9f5eb247..411fff34ae0 100644 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -27,14 +27,6 @@ set(llkdu_HEADER_FILES list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES}) -# Our KDU package is built with KDU_X86_INTRINSICS in its .vcxproj file. -# Unless that macro is also set for every consumer build, KDU freaks out, -# spamming the viewer log with alignment FUD. -set_source_files_properties(${llkdu_SOURCE_FILES} - PROPERTIES - COMPILE_DEFINITIONS - "KDU_X86_INTRINSICS") - if (USE_KDU) add_library (llkdu ${llkdu_SOURCE_FILES}) @@ -42,10 +34,7 @@ if (USE_KDU) target_include_directories( llkdu INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Add tests - # ND: llkdu tests are very strange as they include stubs for KDU classes/methods - # if not having access to the right KDU version this test will fail to compile, incidentally I do not - # have access to a matching version of KDU and thus cannot get this tests to compile - if (LL_TESTS_KDU) + if (LL_TESTS) include(LLAddBuildTest) include(Tut) SET(llkdu_TEST_SOURCE_FILES @@ -62,6 +51,6 @@ if (USE_KDU) set_property( SOURCE ${llkdu_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_INCLUDE_DIRS ${llimage_include_dir}) LL_ADD_PROJECT_UNIT_TESTS(llkdu "${llkdu_TEST_SOURCE_FILES}") - endif (LL_TESTS_KDU) + endif (LL_TESTS) endif (USE_KDU) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index b824fd83851..7eba9494a62 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -163,6 +163,7 @@ class LLKDUDecodeState S32 mNumComponents; bool mUseYCC; kdu_dims mDims; + kdu_push_pull_params mParams; kdu_sample_allocator mAllocator; kdu_tile_comp mComps[4]; kdu_line_buf mLines[4]; @@ -255,7 +256,7 @@ LLImageJ2CKDU::LLImageJ2CKDU() : LLImageJ2CImpl(), mCodeStreamp(), mTPosp(), mTileIndicesp(), - mRawImagep(NULL), + mRawImagep(nullptr), mDecodeState(), mBlocksSize(-1), mPrecinctsSize(-1), @@ -295,17 +296,17 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod // two U32s and a pointer, so it's not as if it would be a huge overhead // to allocate a new one every time. // Also -- why is base.getData() tested specifically here? If that returns - // NULL, shouldn't we bail out of the whole method? + // nullptr, shouldn't we bail out of the whole method? if (!mInputp && base.getData()) { // The compressed data has been loaded // Setup the source for the codestream - mInputp.reset(new LLKDUMemSource(base.getData(), data_size)); + mInputp = std::make_unique(base.getData(), data_size); } if (mInputp) { - // This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset(). + // This is LLKDUMemSource::reset(), not std::unique_ptr::reset(). mInputp->reset(); } @@ -315,7 +316,7 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod // *TODO: This seems to be wrong. The base class should have no idea of // how j2c compression works so no good way of computing what's the byte // range to be used. - mCodeStreamp->set_max_bytes(max_bytes, true); + mCodeStreamp->set_max_bytes(max_bytes); // If you want to flip or rotate the image for some reason, change // the resolution, or identify a restricted region of interest, this is @@ -461,8 +462,8 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco mCodeStreamp->change_appearance(false, true, false); // Apply loading discard level and cropping if required - kdu_dims* region_kdu = NULL; - if (region != NULL) + kdu_dims* region_kdu = nullptr; + if (region != nullptr) { region_kdu = new kdu_dims; region_kdu->pos.x = region[0]; @@ -479,7 +480,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco if (region_kdu) { delete region_kdu; - region_kdu = NULL; + region_kdu = nullptr; } // Resize raw_image according to the image to be decoded @@ -490,12 +491,12 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco if (!mTileIndicesp) { - mTileIndicesp.reset(new kdu_dims); + mTileIndicesp = std::make_unique(); } mCodeStreamp->get_valid_tiles(*mTileIndicesp); if (!mTPosp) { - mTPosp.reset(new kdu_coords); + mTPosp = std::make_unique(); mTPosp->y = 0; mTPosp->x = 0; } @@ -505,7 +506,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco base.setLastError(msg.what()); return false; } - catch (kdu_exception kdu_value) + catch (const kdu_exception& kdu_value) { // KDU internally throws kdu_exception. It's possible that such an // exception might leak out into our code. Catch kdu_exception @@ -596,8 +597,7 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco kdu_coords offset = tile_dims.pos - dims.pos; int row_gap = channels*dims.size.x; // inter-row separation kdu_byte *buf = buffer + offset.y*row_gap + offset.x*channels; - mDecodeState.reset(new LLKDUDecodeState(tile, buf, row_gap, - mCodeStreamp.get())); + mDecodeState = std::make_unique(tile, buf, row_gap, mCodeStreamp.get()); } // Do the actual processing F32 remaining_time = limit_time ? decode_time - decode_timer.getElapsedTimeF32().value() : 0.0f; @@ -622,7 +622,7 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco cleanupCodeStream(); return true; // done } - catch (kdu_exception kdu_value) + catch (const kdu_exception& kdu_value) { // KDU internally throws kdu_exception. It's possible that such an // exception might leak out into our code. Catch kdu_exception @@ -831,7 +831,7 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.setLastError(msg.what()); return false; } - catch (kdu_exception kdu_value) + catch (const kdu_exception& kdu_value) { // KDU internally throws kdu_exception. It's possible that such an // exception might leak out into our code. Catch kdu_exception @@ -865,7 +865,7 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) base.setLastError(msg.what()); return false; } - catch (kdu_exception kdu_value) + catch (const kdu_exception& kdu_value) { // KDU internally throws kdu_exception. It's possible that such an // exception might leak out into our code. Catch kdu_exception @@ -997,8 +997,8 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) //std::cout << "Parsing discard level = " << discard_level << std::endl; // Create the input codestream object. setupCodeStream(base, true, MODE_FAST); - mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL); - mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true); + mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, nullptr); + mCodeStreamp->set_max_bytes(KDU_LONG_MAX,false); siz_params *siz_in = mCodeStreamp->access_siz(); // Create the output codestream object. @@ -1094,8 +1094,10 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) void set_default_colour_weights(kdu_params *siz) { + kdu_params *enc = siz->access_cluster(ENC_params); + assert(enc != nullptr); kdu_params *cod = siz->access_cluster(COD_params); - assert(cod != NULL); + assert(cod != nullptr); bool can_use_ycc = true; bool rev0 = false; @@ -1132,7 +1134,7 @@ void set_default_colour_weights(kdu_params *siz) return; } float weight; - if (cod->get(Clev_weights,0,0,weight) || cod->get(Cband_weights,0,0,weight)) + if (enc->get(Clev_weights,0,0,weight) || enc->get(Cband_weights,0,0,weight)) { // Weights already specified explicitly -> nothing to do return; @@ -1141,17 +1143,16 @@ void set_default_colour_weights(kdu_params *siz) // These example weights are adapted from numbers generated by Marcus Nadenau // at EPFL, for a viewing distance of 15 cm and a display resolution of // 300 DPI. - - cod->parse_string("Cband_weights:C0=" + enc->parse_string("Cband_weights:C0=" "{0.0901},{0.2758},{0.2758}," "{0.7018},{0.8378},{0.8378},{1}"); - cod->parse_string("Cband_weights:C1=" + enc->parse_string("Cband_weights:C1=" "{0.0263},{0.0863},{0.0863}," "{0.1362},{0.2564},{0.2564}," "{0.3346},{0.4691},{0.4691}," "{0.5444},{0.6523},{0.6523}," "{0.7078},{0.7797},{0.7797},{1}"); - cod->parse_string("Cband_weights:C2=" + enc->parse_string("Cband_weights:C2=" "{0.0773},{0.1835},{0.1835}," "{0.2598},{0.4130},{0.4130}," "{0.5040},{0.6464},{0.6464}," @@ -1170,7 +1171,7 @@ byte buffer, spacing successive output samples apart by `gap' bytes all necessary level shifting, type conversion, rounding and truncation. */ { int width = src.get_width(); - if (src.get_buf32() != NULL) + if (src.get_buf32() != nullptr) { // Decompressed samples have a 32-bit representation (integer or float) assert(precision >= 8); // Else would have used 16 bit representation kdu_sample32 *sp = src.get_buf32(); @@ -1333,11 +1334,11 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap, mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts,0,0); if (res.which() == 0) // No DWT levels used { - mEngines[c] = kdu_decoder(res.access_subband(LL_BAND),&mAllocator,use_shorts); + mEngines[c] = kdu_decoder(res.access_subband(LL_BAND), &mAllocator, mParams, use_shorts); } else { - mEngines[c] = kdu_synthesis(res,&mAllocator,use_shorts); + mEngines[c] = kdu_synthesis(res, &mAllocator, mParams, use_shorts); } } mAllocator.finalize(*codestreamp); // Actually creates buffering resources @@ -1415,7 +1416,7 @@ kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_cod this->codestream = codestream; codestream.get_valid_tiles(valid_tile_indices); tile_idx = valid_tile_indices.pos; - tile = codestream.open_tile(tile_idx,NULL); + tile = codestream.open_tile(tile_idx, nullptr); // Set up the individual components num_components = codestream.get_num_components(true); @@ -1424,7 +1425,7 @@ kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_cod kdc_component_flow_control *comp = components; for (n = 0; n < num_components; n++, comp++) { - comp->line = NULL; + comp->line = nullptr; comp->reader = img_in; kdu_coords subsampling; codestream.get_subsampling(n,subsampling,true); @@ -1441,12 +1442,12 @@ kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_cod assert(num_components >= 0); tile.set_components_of_interest(num_components); - max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false); + max_buffer_memory = engine.create(codestream, tile, false, nullptr, false, 1, nullptr, nullptr,false); } kdc_flow_control::~kdc_flow_control() { - if (components != NULL) + if (components != nullptr) { delete[] components; } @@ -1473,8 +1474,8 @@ bool kdc_flow_control::advance_components() if (comp->ratio_counter < 0) { found_line = true; - comp->line = engine.exchange_line(n,NULL,NULL); - assert(comp->line != NULL); + comp->line = engine.exchange_line(n,nullptr,nullptr); + assert(comp->line != nullptr); if (comp->line->get_width()) { comp->reader->get(n,*(comp->line),0); @@ -1501,9 +1502,9 @@ void kdc_flow_control::process_components() assert(comp->ratio_counter >= 0); assert(comp->remaining_lines > 0); comp->remaining_lines--; - assert(comp->line != NULL); - engine.exchange_line(n,comp->line,NULL); - comp->line = NULL; + assert(comp->line != nullptr); + engine.exchange_line(n,comp->line,nullptr); + comp->line = nullptr; } } } diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 8037c818687..c9aa0c52508 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -27,12 +27,13 @@ #ifndef LL_LLIMAGEJ2CKDU_H #define LL_LLIMAGEJ2CKDU_H +#include "llpreprocessor.h" + #include "llimagej2c.h" // // KDU core header files // -#define KDU_NO_THREADS #include "kdu_elementary.h" #include "kdu_messaging.h" #include "kdu_params.h" @@ -41,7 +42,6 @@ #include "include_kdu_xxxx.h" #include "kdu_sample_processing.h" -#include #include class LLKDUDecodeState; diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index 177a8ea9763..56aff13c765 100644 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -27,9 +27,9 @@ #ifndef LL_LLKDUMEM_H #define LL_LLKDUMEM_H -// Support classes for reading and writing from memory buffers in KDU -#define KDU_NO_THREADS +#include "llpreprocessor.h" +// Support classes for reading and writing from memory buffers in KDU #define kdu_xxxx "kdu_image.h" #include "include_kdu_xxxx.h" @@ -54,9 +54,7 @@ class LLKDUMemSource: public kdu_core::kdu_compressed_source mCurPos = 0; } - ~LLKDUMemSource() - { - } + ~LLKDUMemSource() = default; int read(kdu_core::kdu_byte *buf, int num_bytes) { @@ -94,9 +92,7 @@ class LLKDUMemTarget: public kdu_core::kdu_compressed_target mOutputSize = &output_size; } - ~LLKDUMemTarget() - { - } + ~LLKDUMemTarget() = default; bool write(const kdu_core::kdu_byte *buf, int num_bytes) { diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index db81d60d9e7..bc52a15c4af 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -80,6 +80,7 @@ U8* LLImageBase::getData() { return NULL; } U8* LLImageBase::reallocateData(S32 ) { return NULL; } void LLImageBase::sanityCheck() { } void LLImageBase::setSize(S32 , S32 , S32 ) { } +bool LLImageBase::isBufferInvalid() const { return false; } LLImageJ2CImpl::~LLImageJ2CImpl() { } @@ -139,18 +140,19 @@ int kdu_tile_comp::get_bit_depth(bool ) { return 8; } bool kdu_tile_comp::get_reversible() { return false; } int kdu_tile_comp::get_num_resolutions() { return 1; } kdu_subband kdu_resolution::access_subband(int ) { kdu_subband a; return a; } -void kdu_resolution::get_dims(kdu_dims& ) { } -int kdu_resolution::which() { return 0; } -int kdu_resolution::get_valid_band_indices(int &) { return 1; } -kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { } +void kdu_resolution::get_dims(kdu_dims& ) const { } +int kdu_resolution::which() const { return 0; } +int kdu_resolution::get_valid_band_indices(int &) const { return 1; } +kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, kdu_push_pull_params&, bool, float, kdu_thread_env*, kdu_thread_queue*) { } //kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { } -kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool, kd_core_local::kd_coremem*) {} +kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) {} kdu_params::~kdu_params() { } +void kdu_params::destroy() { } void kdu_params::set(const char* , int , int , bool ) { } void kdu_params::set(const char* , int , int , int ) { } void kdu_params::finalize_all(bool ) { } void kdu_params::finalize_all(int, bool ) { } -void kdu_params::copy_from(kdu_params*, int, int, int, int, int, bool, bool, bool) { } +void kdu_params::copy_from(kdu_params*, int, int, int, int, int, bool, bool, bool, bool) { } bool kdu_params::parse_string(const char*) { return false; } bool kdu_params::get(const char*, int, int, bool&, bool, bool, bool) { return false; } bool kdu_params::get(const char*, int, int, float&, bool, bool, bool) { return false; } @@ -159,13 +161,13 @@ kdu_params* kdu_params::access_relation(int, int, int, bool) { return NULL; } kdu_params* kdu_params::access_cluster(const char*) { return NULL; } void kdu_codestream::set_fast() { } void kdu_codestream::set_fussy() { } -void kdu_codestream::get_dims(int, kdu_dims&, bool ) { } +void kdu_codestream::get_dims(int, kdu_dims&, bool ) const { } int kdu_codestream::get_min_dwt_levels() { return 5; } int kdu_codestream::get_max_tile_layers() { return 1; } void kdu_codestream::change_appearance(bool, bool, bool, kdu_thread_env *) {} void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { } void kdu_codestream::destroy() { } -void kdu_codestream::collect_timing_stats(int ) { } +void kdu_codestream::collect_timing_stats(int ) const { } void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { } void kdu_codestream::get_valid_tiles(kdu_dims& ) { } void kdu_codestream::create( @@ -182,19 +184,21 @@ void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { } void kdu_codestream::flush(kdu_long *, int, kdu_uint16 *, bool, bool, double, kdu_thread_env*, int) { } void kdu_codestream::set_resilient(bool ) { } int kdu_codestream::get_num_components(bool ) { return 0; } -kdu_long kdu_codestream::get_total_bytes(bool ) { return 0; } +kdu_long kdu_codestream::get_total_bytes(bool ) const { return 0; } kdu_long kdu_codestream::get_compressed_data_memory(bool ) const {return 0; } void kdu_codestream::share_buffering(kdu_codestream ) { } -int kdu_codestream::get_num_tparts() { return 0; } +int kdu_codestream::get_num_tparts() const { return 0; } int kdu_codestream::trans_out(kdu_long, kdu_long*, int, bool, kdu_thread_env* ) { return 0; } bool kdu_codestream::ready_for_flush(kdu_thread_env*) { return false; } siz_params* kdu_codestream::access_siz() { return NULL; } kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; } kdu_codestream_comment kdu_codestream::add_comment(kdu_thread_env*) { kdu_codestream_comment a; return a; } +kdu_codestream_comment kdu_codestream::get_comment(kdu_codestream_comment) { kdu_codestream_comment a; return a; }; void kdu_subband::close_block(kdu_block*, kdu_thread_env*) { } void kdu_subband::get_valid_blocks(kdu_dims &indices) const { } kdu_block * kdu_subband::open_block(kdu_coords, int *, kdu_thread_env *, int, bool) { return NULL; } bool kdu_codestream_comment::put_text(const char*) { return false; } +const char *kdu_codestream_comment::get_text() { return nullptr; }; void kdu_customize_warnings(kdu_message*) { } void kdu_customize_errors(kdu_message*) { } kdu_long kdu_multi_analysis::create( @@ -209,16 +213,18 @@ kdu_long kdu_multi_analysis::create( const kdu_push_pull_params*, kdu_membroker*) { return kdu_long(0); } void kdu_multi_analysis::destroy(kdu_thread_env *) {} +siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { } siz_params::siz_params(kd_core_local::kd_coremem*) : kdu_params(NULL, false, false, false, false, false) { } siz_params::~siz_params() {} void siz_params::finalize(bool ) { } void siz_params::copy_with_xforms(kdu_params*, int, int, bool, bool, bool) { } -int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0; } +int siz_params::write_marker_segment(kdu_output*, kdu_params*, int, int&) { return 0; } bool siz_params::check_marker_segment(kdu_uint16, int, kdu_byte a[], int&) { return false; } -bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { return false; } +int siz_params::read_marker_segment(kdu_uint16 code, int num_bytes, kdu_byte bytes[], int tpart_idx) { return false; } kdu_decoder::kdu_decoder( kdu_subband subband, kdu_sample_allocator*, + kdu_push_pull_params&, bool, float, int, kdu_thread_env*, kdu_thread_queue*, diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index eb29df245a6..bd860adc319 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -6,6 +6,7 @@ include(00-Common) include(LLCommon) include(bugsplat) include(Boost) +include(SSE2NEON) set(llmath_SOURCE_FILES llbbox.cpp @@ -59,6 +60,7 @@ set(llmath_HEADER_FILES llmath.h llmatrix3a.h llmatrix3a.inl + llmatrix4a.h llmodularmath.h lloctree.h llperlin.h @@ -99,7 +101,7 @@ list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) add_library (llmath ${llmath_SOURCE_FILES}) -target_link_libraries(llmath llcommon llmeshoptimizer) +target_link_libraries(llmath llcommon llmeshoptimizer ll::sse2neon) target_include_directories( llmath INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Add tests diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h index 5617eaebde0..3a4e09a5989 100644 --- a/indra/llmath/llbbox.h +++ b/indra/llmath/llbbox.h @@ -95,6 +95,10 @@ class LLBBox bool mEmpty; // Nothing has been added to this bbox yet }; +static_assert(std::is_trivially_copyable::value, "LLBBox must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLBBox must be trivial move"); +static_assert(std::is_standard_layout::value, "LLBBox must be a standard layout type"); + //LLBBox operator*(const LLBBox &a, const LLMatrix4 &b); diff --git a/indra/llmath/llbboxlocal.h b/indra/llmath/llbboxlocal.h index e215e554608..f743bc0ee41 100644 --- a/indra/llmath/llbboxlocal.h +++ b/indra/llmath/llbboxlocal.h @@ -61,5 +61,8 @@ class LLBBoxLocal LLBBoxLocal operator*(const LLBBoxLocal &a, const LLMatrix4 &b); +static_assert(std::is_trivially_copyable::value, "LLBBoxLocal must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLBBoxLocal must be trivial move"); +static_assert(std::is_standard_layout::value, "LLBBoxLocal must be a standard layout type"); #endif // LL_BBOXLOCAL_H diff --git a/indra/llmath/llline.h b/indra/llmath/llline.h index e98e173d1f7..fa151f8b20b 100644 --- a/indra/llmath/llline.h +++ b/indra/llmath/llline.h @@ -40,7 +40,7 @@ class LLLine public: LLLine(); LLLine( const LLVector3& first_point, const LLVector3& second_point ); - virtual ~LLLine() {}; + ~LLLine() = default; void setPointDirection( const LLVector3& first_point, const LLVector3& second_point ); void setPoints( const LLVector3& first_point, const LLVector3& second_point ); @@ -76,5 +76,8 @@ class LLLine LLVector3 mDirection; }; +static_assert(std::is_trivially_copyable::value, "LLLine must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLLine must be trivial move"); +static_assert(std::is_standard_layout::value, "LLLine must be a standard layout type"); #endif diff --git a/indra/llmath/llmatrix3a.h b/indra/llmath/llmatrix3a.h index dff6604ae5b..9b173c22edd 100644 --- a/indra/llmath/llmatrix3a.h +++ b/indra/llmath/llmatrix3a.h @@ -56,7 +56,7 @@ class LLMatrix3a ////////////////////////// // Ctor - LLMatrix3a() {} + LLMatrix3a() = default; // Ctor for setting by columns inline LLMatrix3a( const LLVector4a& c0, const LLVector4a& c1, const LLVector4a& c2 ); @@ -115,14 +115,18 @@ class LLMatrix3a }; +static_assert(std::is_trivial::value, "LLMatrix3a must be a trivial type"); + class LLRotation : public LLMatrix3a { public: - LLRotation() {} + LLRotation() = default; // Returns true if this rotation is orthonormal with det ~= 1 inline bool isOkRotation() const; }; +static_assert(std::is_trivial::value, "LLRotation must be a trivial type"); + #endif diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 3b423f783a0..377203098e2 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -36,10 +36,7 @@ class LLMatrix4a public: LL_ALIGN_16(LLVector4a mMatrix[4]); - LLMatrix4a() - { - - } + LLMatrix4a() = default; explicit LLMatrix4a(const LLMatrix4& val) { @@ -228,6 +225,8 @@ class LLMatrix4a const LLVector4a& getTranslation() const { return mMatrix[3]; } }; +static_assert(std::is_trivial::value, "LLMatrix4a must be a trivial type"); + inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat) { LLVector4a result; diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h index 4e8546e32b0..832004bb644 100644 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -43,7 +43,7 @@ class LLPlane public: // Constructors - LLPlane() {}; // no default constructor + LLPlane() = default; LLPlane(const LLVector3 &p0, F32 d) { setVec(p0, d); } LLPlane(const LLVector3 &p0, const LLVector3 &n) { setVec(p0, n); } inline void setVec(const LLVector3 &p0, F32 d) { mV.set(p0[0], p0[1], p0[2], d); } @@ -104,6 +104,7 @@ class LLPlane LLVector4a mV; } LL_ALIGN_POSTFIX(16); +static_assert(std::is_trivial::value, "LLPlane must be a trivial type"); #endif // LL_LLPLANE_H diff --git a/indra/llmath/llquaternion.h b/indra/llmath/llquaternion.h index 762d13eded7..472d7ca62dc 100644 --- a/indra/llmath/llquaternion.h +++ b/indra/llmath/llquaternion.h @@ -174,6 +174,10 @@ class LLQuaternion //static U32 mMultCount; }; +static_assert(std::is_trivially_copyable::value, "LLQuaternion must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLQuaternion must be trivial move"); +static_assert(std::is_standard_layout::value, "LLQuaternion must be a standard layout type"); + inline LLSD LLQuaternion::getValue() const { LLSD ret; diff --git a/indra/llmath/llquaternion2.h b/indra/llmath/llquaternion2.h index 902bfb71342..c9dcc4573fa 100644 --- a/indra/llmath/llquaternion2.h +++ b/indra/llmath/llquaternion2.h @@ -49,7 +49,7 @@ class LLQuaternion2 ////////////////////////// // Ctor - LLQuaternion2() {} + LLQuaternion2() = default; // Ctor from LLQuaternion explicit LLQuaternion2( const class LLQuaternion& quat ); @@ -102,4 +102,6 @@ class LLQuaternion2 }; +static_assert(std::is_trivial::value, "LLQuaternion2 must be a trivial type"); + #endif diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h index 317578da06d..0a3da2fee0c 100644 --- a/indra/llmath/llrect.h +++ b/indra/llmath/llrect.h @@ -51,10 +51,6 @@ template class LLRectBase LLRectBase(): mLeft(0), mTop(0), mRight(0), mBottom(0) {} - LLRectBase(const LLRectBase &r): - mLeft(r.mLeft), mTop(r.mTop), mRight(r.mRight), mBottom(r.mBottom) - {} - LLRectBase(Type left, Type top, Type right, Type bottom): mLeft(left), mTop(top), mRight(right), mBottom(bottom) {} @@ -295,4 +291,8 @@ template LLRectBase LLRectBase::null(0,0,0,0); typedef LLRectBase LLRect; typedef LLRectBase LLRectf; +static_assert(std::is_trivially_copyable::value, "LLRect must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLRect must be trivial move"); +static_assert(std::is_standard_layout::value, "LLRect must be a standard layout type"); + #endif diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h index 40953dc2e81..b27b034cf3c 100644 --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -31,16 +31,26 @@ #error "Please include llmath.h before this file." #endif -#if ( ( LL_DARWIN || LL_LINUX ) && !(__SSE2__) ) || ( LL_WINDOWS && ( _M_IX86_FP < 2 && ADDRESS_SIZE == 32 ) ) -#error SSE2 not enabled. LLVector4a and related class will not compile. +// the check for this error case must be split into multiple parts +// because some versions of VS complain about '__SSE2__' +#if ( ( LL_DARWIN || LL_LINUX ) ) + #if !(__SSE2__) && !(__arm64__) && !(__aarch64__) + #error SSE2 not enabled. LLVector4a and related class will not compile. + #endif +#elif ( LL_WINDOWS && ( _M_IX86_FP < 2 && ADDRESS_SIZE == 32 ) ) + #error SSE2 not enabled. LLVector4a and related class will not compile. #endif #if !LL_WINDOWS #include #endif +#if defined(__arm64__) || defined(__aarch64__) +#include "sse2neon.h" +#else #include #include +#endif #include "llmemory.h" #include "llsimdtypes.h" diff --git a/indra/llmath/llsimdtypes.h b/indra/llmath/llsimdtypes.h index a407f51029e..6c4f55b0c08 100644 --- a/indra/llmath/llsimdtypes.h +++ b/indra/llmath/llsimdtypes.h @@ -36,7 +36,7 @@ typedef __m128 LLQuad; class LLBool32 { public: - inline LLBool32() {} + inline LLBool32() = default; inline LLBool32(int rhs) : m_bool(rhs) {} inline LLBool32(unsigned int rhs) : m_bool(rhs) {} inline LLBool32(bool rhs) { m_bool = static_cast(rhs); } @@ -46,13 +46,15 @@ class LLBool32 inline operator bool() const { return static_cast(m_bool); } private: - int m_bool{ 0 }; + int m_bool; }; +static_assert(std::is_trivial::value, "LLBool32 must be a standard layout type"); + class LLSimdScalar { public: - inline LLSimdScalar() {} + inline LLSimdScalar() = default; inline LLSimdScalar(LLQuad q) { mQ = q; @@ -100,7 +102,9 @@ class LLSimdScalar } private: - LLQuad mQ{}; + LLQuad mQ; }; +static_assert(std::is_trivial::value, "LLSimdScalar must be a standard layout type"); + #endif //LL_SIMD_TYPES_H diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 4004852e065..764a3b94e6a 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -95,10 +95,7 @@ class alignas(16) LLVector4a //////////////////////////////////// //LLVector4a is plain data which should never have a default constructor or destructor(malloc&free won't trigger it) - LLVector4a() - { //DO NOT INITIALIZE -- The overhead is completely unnecessary - ll_assert_aligned(this,16); - } + LLVector4a() = default; LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f) { @@ -361,8 +358,6 @@ class alignas(16) LLVector4a //////////////////////////////////// // Do NOT add aditional operators without consulting someone with SSE experience - inline const LLVector4a& operator= ( const LLVector4a& rhs ); - inline const LLVector4a& operator= ( const LLQuad& rhs ); inline operator LLQuad() const; @@ -378,9 +373,11 @@ class alignas(16) LLVector4a }; private: - LLQuad mQ{}; + LLQuad mQ; }; +static_assert(std::is_trivial::value, "LLVector4a must be a trivial type"); + inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p) { min.setMin(min, p); diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 36dbec078cb..443a46c317f 100644 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -115,7 +115,7 @@ inline void LLVector4a::set(F32 x, F32 y, F32 z, F32 w) // Set to all zeros inline void LLVector4a::clear() { - mQ = LLVector4a::getZero().mQ; + mQ = _mm_setzero_ps(); } inline void LLVector4a::splat(const F32 x) @@ -272,6 +272,9 @@ inline void LLVector4a::setCross3(const LLVector4a& a, const LLVector4a& b) // Set all elements to the dot product of the x, y, and z elements in a and b inline void LLVector4a::setAllDot3(const LLVector4a& a, const LLVector4a& b) { +#if (defined(__arm64__) || defined(__aarch64__)) + mQ = _mm_dp_ps(a.mQ, b.mQ, 0x7f); +#else // ab = { a[W]*b[W], a[Z]*b[Z], a[Y]*b[Y], a[X]*b[X] } const LLQuad ab = _mm_mul_ps( a.mQ, b.mQ ); // yzxw = { a[W]*b[W], a[Z]*b[Z], a[X]*b[X], a[Y]*b[Y] } @@ -284,11 +287,15 @@ inline void LLVector4a::setAllDot3(const LLVector4a& a, const LLVector4a& b) const __m128i zSplat = _mm_shuffle_epi32(_mm_castps_si128(ab), _MM_SHUFFLE( 2, 2, 2, 2 )); // mQ = { a[Z] * b[Z] + a[Y] * b[Y] + a[X] * b[X], same, same, same } mQ = _mm_add_ps(_mm_castsi128_ps(zSplat), xPlusYSplat); +#endif } // Set all elements to the dot product of the x, y, z, and w elements in a and b inline void LLVector4a::setAllDot4(const LLVector4a& a, const LLVector4a& b) { +#if (defined(__arm64__) || defined(__aarch64__)) + mQ = _mm_dp_ps(a.mQ, b.mQ, 0xff); +#else // ab = { a[W]*b[W], a[Z]*b[Z], a[Y]*b[Y], a[X]*b[X] } const LLQuad ab = _mm_mul_ps( a.mQ, b.mQ ); // yzxw = { a[W]*b[W], a[Z]*b[Z], a[X]*b[X], a[Y]*b[Y] } @@ -301,21 +308,29 @@ inline void LLVector4a::setAllDot4(const LLVector4a& a, const LLVector4a& b) // mQ = { a[W]*b[W] + a[Z] * b[Z] + a[Y] * b[Y] + a[X] * b[X], same, same, same } mQ = _mm_add_ps(xPlusYSplat, zPlusWSplat); +#endif } // Return the 3D dot product of this vector and b inline LLSimdScalar LLVector4a::dot3(const LLVector4a& b) const { +#if (defined(__arm64__) || defined(__aarch64__)) + return _mm_dp_ps(mQ, b.mQ, 0x7f); +#else const LLQuad ab = _mm_mul_ps( mQ, b.mQ ); const LLQuad splatY = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128(ab), _MM_SHUFFLE(1, 1, 1, 1) ) ); const LLQuad splatZ = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128(ab), _MM_SHUFFLE(2, 2, 2, 2) ) ); const LLQuad xPlusY = _mm_add_ps( ab, splatY ); return _mm_add_ps( xPlusY, splatZ ); +#endif } // Return the 4D dot product of this vector and b inline LLSimdScalar LLVector4a::dot4(const LLVector4a& b) const { +#if (defined(__arm64__) || defined(__aarch64__)) + return _mm_dp_ps(mQ, b.mQ, 0xff); +#else // ab = { w, z, y, x } const LLQuad ab = _mm_mul_ps( mQ, b.mQ ); // upperProdsInLowerElems = { y, x, y, x } @@ -325,6 +340,7 @@ inline LLSimdScalar LLVector4a::dot4(const LLVector4a& b) const // shuffled = { z+x, z+x, z+x, z+x } const LLQuad shuffled = _mm_castsi128_ps( _mm_shuffle_epi32( _mm_castps_si128( sumOfPairs ), _MM_SHUFFLE(1, 1, 1, 1) ) ); return _mm_add_ss( sumOfPairs, shuffled ); +#endif } // Normalize this vector with respect to the x, y, and z components only. Accurate to 22 bites of precision. W component is destroyed @@ -593,12 +609,6 @@ inline bool LLVector4a::equals3(const LLVector4a& rhs, F32 tolerance ) const //////////////////////////////////// // Do NOT add aditional operators without consulting someone with SSE experience -inline const LLVector4a& LLVector4a::operator= ( const LLVector4a& rhs ) -{ - mQ = rhs.mQ; - return *this; -} - inline const LLVector4a& LLVector4a::operator= ( const LLQuad& rhs ) { mQ = rhs; diff --git a/indra/llmath/llvector4logical.h b/indra/llmath/llvector4logical.h index 70759eef5c9..77cb5862e56 100644 --- a/indra/llmath/llvector4logical.h +++ b/indra/llmath/llvector4logical.h @@ -61,7 +61,7 @@ class LLVector4Logical }; // Empty default ctor - LLVector4Logical() {} + LLVector4Logical() = default; LLVector4Logical( const LLQuad& quad ) { @@ -120,7 +120,9 @@ class LLVector4Logical private: - LLQuad mQ{}; + LLQuad mQ; }; +static_assert(std::is_trivial::value, "LLVector4Logical must be a standard layout type"); + #endif //LL_VECTOR4ALOGICAL_H diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 7c602536186..b3cb278d599 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5713,6 +5713,8 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) { try { + // providing mIndices should help avoid unused vertices + // but those should have been filtered out on upload vert_count = static_cast(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count)); } catch (std::bad_alloc&) @@ -5722,10 +5724,16 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) } } - if (vert_count < 65535 && vert_count != 0) + // Probably should be using meshopt_remapVertexBuffer instead of remaping manually + if (vert_count < 65535 && vert_count > 0) { //copy results back into volume resizeVertices(vert_count); + if (mNumVertices == 0) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Failed to allocate memory for resizeVertices(" << vert_count << ")" << LL_ENDL; + } if (!data.w.empty()) { @@ -5738,13 +5746,27 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) { U32 src_idx = i; U32 dst_idx = remap[i]; - if (dst_idx >= (U32)mNumVertices) + if (dst_idx == U32_MAX) + { + // Unused indices? Probably need to resize mIndices + dst_idx = mNumVertices - 1; + llassert(false); + LL_DEBUGS_ONCE("LLVOLUME") << "U32_MAX destination index, substituting" << LL_ENDL; + } + else if (dst_idx >= (U32)mNumVertices) { dst_idx = mNumVertices - 1; // Shouldn't happen, figure out what gets returned in remap and why. llassert(false); LL_DEBUGS_ONCE("LLVOLUME") << "Invalid destination index, substituting" << LL_ENDL; } + if (src_idx >= (U32)data.p.size()) + { + // data.p.size() is supposed to be equal to mNumIndices + src_idx = (U32)(data.p.size() - 1); + llassert(false); + LL_DEBUGS_ONCE("LLVOLUME") << "Invalid source index, substituting" << LL_ENDL; + } mIndices[i] = dst_idx; mPositions[dst_idx].load3(data.p[src_idx].mV); @@ -5778,7 +5800,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) } else { - if (vert_count == 0) + if (vert_count <= 0) { LL_WARNS_ONCE("LLVOLUME") << "meshopt_generateVertexRemapMulti failed to process a model or model was invalid" << LL_ENDL; } diff --git a/indra/llmath/m3math.h b/indra/llmath/m3math.h index cd14290246a..36661d2cb0d 100644 --- a/indra/llmath/m3math.h +++ b/indra/llmath/m3math.h @@ -142,6 +142,10 @@ class LLMatrix3 friend std::ostream& operator<<(std::ostream& s, const LLMatrix3 &a); // Stream a }; +static_assert(std::is_trivially_copyable::value, "LLMatrix3 must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLMatrix3 must be trivial move"); +static_assert(std::is_standard_layout::value, "LLMatrix3 must be a standard layout type"); + inline LLMatrix3::LLMatrix3(void) { mMatrix[0][0] = 1.f; diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index a9853fe7e92..1724a50601e 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -156,10 +156,6 @@ LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw) mMatrix[3][3] = 1.f; } -LLMatrix4::~LLMatrix4(void) -{ -} - // Clear and Assignment Functions const LLMatrix4& LLMatrix4::setZero() diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index b0f8c90cdfd..f164779283a 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -119,8 +119,6 @@ class LLMatrix4 const LLVector4 &pos); // Initializes Matrix with Euler angles LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw); // Initializes Matrix with Euler angles - ~LLMatrix4(void); // Destructor - LLSD getValue() const; void setValue(const LLSD&); @@ -242,6 +240,10 @@ class LLMatrix4 friend std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a); // Stream a }; +static_assert(std::is_trivially_copyable::value, "LLMatrix4 must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLMatrix4 must be trivial move"); +static_assert(std::is_standard_layout::value, "LLMatrix4 must be a standard layout type"); + inline const LLMatrix4& LLMatrix4::setIdentity() { mMatrix[0][0] = 1.f; diff --git a/indra/llmath/tests/llquaternion_test.cpp b/indra/llmath/tests/llquaternion_test.cpp index aa3c0ad8431..ba18d54d559 100644 --- a/indra/llmath/tests/llquaternion_test.cpp +++ b/indra/llmath/tests/llquaternion_test.cpp @@ -349,9 +349,9 @@ namespace tut ensure( "2. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed", is_approx_equal(-58153.5390f, result.mV[0]) && - (183787.8125f == result.mV[1]) && - (116864.164063f == result.mV[2]) && - (78.099998f == result.mV[3])); + is_approx_equal(183787.8125f, result.mV[1]) && + is_approx_equal(116864.164063f, result.mV[2]) && + is_approx_equal(78.099998f, result.mV[3])); } //test case for LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) fn. diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h index 6b9d37535b2..b31e4056a38 100644 --- a/indra/llmath/v2math.h +++ b/indra/llmath/v2math.h @@ -110,6 +110,9 @@ class LLVector2 friend std::ostream& operator<<(std::ostream& s, const LLVector2 &a); // Stream a }; +static_assert(std::is_trivially_copyable::value, "LLVector2 must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLVector2 must be trivial move"); +static_assert(std::is_standard_layout::value, "LLVector2 must be a standard layout type"); // Non-member functions diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 48b36e7c8a1..7357d935996 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -144,8 +144,11 @@ class LLColor3 inline void exp(); // Do an exponential on the color }; -LLColor3 lerp(const LLColor3& a, const LLColor3& b, F32 u); +static_assert(std::is_trivially_copyable::value, "LLColor3 must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLColor3 must be trivial move"); +static_assert(std::is_standard_layout::value, "LLColor3 must be a standard layout type"); +LLColor3 lerp(const LLColor3& a, const LLColor3& b, F32 u); void LLColor3::clamp() { // Clamp the color... diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h index fcce2c30eb8..7c56cf138d5 100644 --- a/indra/llmath/v3dmath.h +++ b/indra/llmath/v3dmath.h @@ -129,6 +129,10 @@ class LLVector3d static bool parseVector3d(const std::string& buf, LLVector3d* value); }; +static_assert(std::is_trivially_copyable::value, "LLVector3d must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLVector3d must be trivial move"); +static_assert(std::is_standard_layout::value, "LLVector3d must be a standard layout type"); + typedef LLVector3d LLGlobalVec; inline const LLVector3d &LLVector3d::set(const LLVector3 &vec) diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 098ca5218c9..196ecdcf7d9 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -164,6 +164,10 @@ class LLVector3 static bool parseVector3(const std::string& buf, LLVector3* value); }; +static_assert(std::is_trivially_copyable::value, "LLVector3 must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLVector3 must be trivial move"); +static_assert(std::is_standard_layout::value, "LLVector3 must be a standard layout type"); + typedef LLVector3 LLSimLocalVec; // Non-member functions diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index 2f1cb21113b..d48020c2233 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -231,6 +231,10 @@ class LLColor4 inline void clamp(); }; +static_assert(std::is_trivially_copyable::value, "LLColor4 must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLColor4 must be trivial move"); +static_assert(std::is_standard_layout::value, "LLColor4 must be a standard layout type"); + // Non-member functions F32 distVec(const LLColor4& a, const LLColor4& b); // Returns distance between a and b F32 distVec_squared(const LLColor4& a, const LLColor4& b); // Returns distance squared between a and b diff --git a/indra/llmath/v4coloru.h b/indra/llmath/v4coloru.h index bfa998bc58a..e495fd3eea5 100644 --- a/indra/llmath/v4coloru.h +++ b/indra/llmath/v4coloru.h @@ -123,6 +123,10 @@ class LLColor4U static LLColor4U blue; }; +static_assert(std::is_trivially_copyable::value, "LLColor4U must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLColor4U must be trivial move"); +static_assert(std::is_standard_layout::value, "LLColor4U must be a standard layout type"); + // Non-member functions F32 distVec(const LLColor4U& a, const LLColor4U& b); // Returns distance between a and b F32 distVec_squared(const LLColor4U& a, const LLColor4U& b); // Returns distance squared between a and b diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h index 1cbd0d9a783..edfc2f8592b 100644 --- a/indra/llmath/v4math.h +++ b/indra/llmath/v4math.h @@ -146,6 +146,10 @@ class LLVector4 friend LLVector4 operator-(const LLVector4 &a); // Return vector -a }; +static_assert(std::is_trivially_copyable::value, "LLVector4 must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLVector4 must be trivial move"); +static_assert(std::is_standard_layout::value, "LLVector4 must be a standard layout type"); + // Non-member functions F32 angle_between(const LLVector4 &a, const LLVector4 &b); // Returns angle (radians) between a and b bool are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon = F_APPROXIMATELY_ZERO); // Returns true if a and b are very close to parallel diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 6a663a8e97c..5c7b1c42350 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -50,7 +50,7 @@ static const U32 DEFAULT_POOL_SIZE = 5; // SL-14399: When we teleport to a brand-new simulator, the coprocedure queue // gets absolutely slammed with fetch requests. Make this queue effectively // unlimited. -const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*1024; +const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*512; //========================================================================= class LLCoprocedurePool: private boost::noncopyable @@ -58,7 +58,7 @@ class LLCoprocedurePool: private boost::noncopyable public: typedef LLCoprocedureManager::CoProcedure_t CoProcedure_t; - LLCoprocedurePool(const std::string &name, size_t size); + LLCoprocedurePool(const std::string &name, size_t size, size_t queue_size); ~LLCoprocedurePool(); /// Places the coprocedure on the queue for processing. @@ -118,7 +118,7 @@ class LLCoprocedurePool: private boost::noncopyable typedef std::shared_ptr CoprocQueuePtr; std::string mPoolName; - size_t mPoolSize, mActiveCoprocsCount, mPending; + size_t mPoolSize, mQueueSize, mActiveCoprocsCount, mPending; CoprocQueuePtr mPendingCoprocs; LLTempBoundListener mStatusListener; @@ -138,10 +138,25 @@ LLCoprocedureManager::LLCoprocedureManager() LLCoprocedureManager::~LLCoprocedureManager() { - close(); + try + { + close(); + } + catch (const boost::fibers::fiber_error&) + { + LL_WARNS() << "Fiber error during ~LLCoprocedureManager()" << LL_ENDL; + } + catch (const std::exception& e) + { + // Shutting down, just log it + LL_WARNS() << "Exception during ~LLCoprocedureManager(): " << e.what() << LL_ENDL; + } + mPropertyQueryFn.clear(); + mPropertyDefineFn.clear(); + mPoolMap.clear(); } -void LLCoprocedureManager::initializePool(const std::string &poolName) +void LLCoprocedureManager::initializePool(const std::string &poolName, size_t queue_size) { poolMap_t::iterator it = mPoolMap.find(poolName); @@ -180,7 +195,7 @@ void LLCoprocedureManager::initializePool(const std::string &poolName) LL_WARNS("CoProcMgr") << "LLCoprocedureManager: No setting for \"" << keyName << "\" setting pool size to default of " << size << LL_ENDL; } - poolPtr_t pool(new LLCoprocedurePool(poolName, size)); + poolPtr_t pool(new LLCoprocedurePool(poolName, size, queue_size)); LL_ERRS_IF(!pool, "CoprocedureManager") << "Unable to create pool named \"" << poolName << "\" FATAL!" << LL_ENDL; bool inserted = mPoolMap.emplace(poolName, pool).second; @@ -212,7 +227,8 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd mPropertyQueryFn = queryfn; mPropertyDefineFn = updatefn; - initializePool("Upload"); + constexpr size_t UPLOAD_QUEUE_SIZE = 2048; + initializePool("Upload", UPLOAD_QUEUE_SIZE); initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS // "ExpCache" pool gets initialized in LLExperienceCache // asset storage pool gets initialized in LLViewerAssetStorage @@ -296,17 +312,19 @@ void LLCoprocedureManager::close(const std::string &pool) } //========================================================================= -LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): +LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size, size_t queue_size): mPoolName(poolName), mPoolSize(size), + mQueueSize(queue_size), mActiveCoprocsCount(0), mPending(0), mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), mCoroMapping() { + llassert_always(mQueueSize > mPoolSize); // queue should be able to fit pool try { - mPendingCoprocs = std::make_shared(LLCoprocedureManager::DEFAULT_QUEUE_SIZE); + mPendingCoprocs = std::make_shared(mQueueSize); // store in our LLTempBoundListener so that when the LLCoprocedurePool is // destroyed, we implicitly disconnect from this LLEventPump // Monitores application status @@ -357,11 +375,27 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter)); } - LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL; + LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << mQueueSize << LL_ENDL; } LLCoprocedurePool::~LLCoprocedurePool() { + try + { + close(); // should have been closed already, but shouldn't hurt + mStatusListener.disconnect(); + mPendingCoprocs.reset(); + mCoroMapping.clear(); + } + catch (const boost::fibers::fiber_error&) + { + LL_WARNS() << "Fiber error during ~LLCoprocedurePool() " << mPoolName << LL_ENDL; + } + catch (const std::exception& e) + { + // Shutting down, just log it + LL_WARNS() << "Exception " << e.what() << " during ~LLCoprocedurePool() in " << mPoolName << LL_ENDL; + } } //------------------------------------------------------------------------- @@ -376,7 +410,7 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced << "\" at " << mPending << LL_ENDL; - if (mPending >= (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1)) + if (mPending >= (mQueueSize - 1)) { // If it's all used up (not supposed to happen, // fetched should cap it), we are going to crash diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 6c6e5066545..485333657ca 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -79,7 +79,7 @@ class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager > void close(); void close(const std::string &pool); - void initializePool(const std::string &poolName); + void initializePool(const std::string &poolName, size_t queue_size = DEFAULT_QUEUE_SIZE); private: diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp index 83a070df320..78cca47456e 100644 --- a/indra/llmessage/llexperiencecache.cpp +++ b/indra/llmessage/llexperiencecache.cpp @@ -110,7 +110,8 @@ void LLExperienceCache::initSingleton() cache_stream >> (*this); } - LLCoprocedureManager::instance().initializePool("ExpCache"); + constexpr size_t CORO_QUEUE_SIZE = 2048; + LLCoprocedureManager::instance().initializePool("ExpCache", CORO_QUEUE_SIZE); LLCoros::instance().launch("LLExperienceCache::idleCoro", boost::bind(&LLExperienceCache::idleCoro, this)); diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index f6ed43a4e4c..a2d09f4f365 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -1051,7 +1051,7 @@ void LLXferManager::retransmitUnackedPackets() // Re-build mOutgoingHosts data updateHostStatus(); - F32 et; + F32 et = 0.f; iter = mSendList.begin(); while (iter != mSendList.end()) { diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 21dbf35783a..f42cbfdac7a 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -714,6 +714,9 @@ char const* const _PREHASH_FirstName = LLMessageStringTable::getInstance()->getS char const* const _PREHASH_AttachedSoundGainChange = LLMessageStringTable::getInstance()->getString("AttachedSoundGainChange"); char const* const _PREHASH_LocationID = LLMessageStringTable::getInstance()->getString("LocationID"); char const* const _PREHASH_Running = LLMessageStringTable::getInstance()->getString("Running"); +char const* const _PREHASH_Mono = LLMessageStringTable::getInstance()->getString("Mono"); +char const* const _PREHASH_Luau = LLMessageStringTable::getInstance()->getString("Luau"); +char const* const _PREHASH_LuauLanguage = LLMessageStringTable::getInstance()->getString("LuauLanguage"); char const* const _PREHASH_AgentThrottle = LLMessageStringTable::getInstance()->getString("AgentThrottle"); char const* const _PREHASH_NeighborList = LLMessageStringTable::getInstance()->getString("NeighborList"); char const* const _PREHASH_PathTaperX = LLMessageStringTable::getInstance()->getString("PathTaperX"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 8a2ad1587c8..53f8123b353 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -714,6 +714,9 @@ extern char const* const _PREHASH_FirstName; extern char const* const _PREHASH_AttachedSoundGainChange; extern char const* const _PREHASH_LocationID; extern char const* const _PREHASH_Running; +extern char const* const _PREHASH_Mono; +extern char const* const _PREHASH_Luau; +extern char const* const _PREHASH_LuauLanguage; extern char const* const _PREHASH_AgentThrottle; extern char const* const _PREHASH_NeighborList; extern char const* const _PREHASH_PathTaperX; diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 14a69afe6eb..e008a4093ee 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -31,18 +31,10 @@ set(llplugin_HEADER_FILES llpluginsharedmemory.h ) -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) - list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) target_include_directories( llplugin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries( llplugin llcommon llmath llrender llmessage ) +target_link_libraries( llplugin llcommon llmath llmessage llxml ) add_subdirectory(slplugin) diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 8a356da93a9..77a4b08af55 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -132,9 +132,13 @@ void LLPluginClassMedia::reset() mLastMouseY = 0; mStatus = LLPluginClassMediaOwner::MEDIA_NONE; mSleepTime = 1.0f / 100.0f; + mCanUndo = false; + mCanRedo = false; mCanCut = false; mCanCopy = false; mCanPaste = false; + mCanDoDelete = false; + mCanSelectAll = false; mMediaName.clear(); mMediaDescription.clear(); mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f); @@ -907,6 +911,18 @@ void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username, sendMessage(message); } +void LLPluginClassMedia::undo() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_undo"); + sendMessage(message); +} + +void LLPluginClassMedia::redo() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_redo"); + sendMessage(message); +} + void LLPluginClassMedia::cut() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut"); @@ -925,6 +941,24 @@ void LLPluginClassMedia::paste() sendMessage(message); } +void LLPluginClassMedia::doDelete() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_delete"); + sendMessage(message); +} + +void LLPluginClassMedia::selectAll() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_select_all"); + sendMessage(message); +} + +void LLPluginClassMedia::showPageSource() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_show_source"); + sendMessage(message); +} + void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache, const std::string &username, const std::string &user_data_path_cef_log) @@ -1178,6 +1212,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) } else if(message_name == "edit_state") { + if(message.hasValue("undo")) + { + mCanUndo = message.getValueBoolean("undo"); + } + if(message.hasValue("redo")) + { + mCanRedo = message.getValueBoolean("redo"); + } if(message.hasValue("cut")) { mCanCut = message.getValueBoolean("cut"); @@ -1190,6 +1232,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) { mCanPaste = message.getValueBoolean("paste"); } + if (message.hasValue("delete")) + { + mCanDoDelete = message.getValueBoolean("delete"); + } + if (message.hasValue("select_all")) + { + mCanSelectAll = message.getValueBoolean("select_all"); + } } else if(message_name == "name_text") { diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index d74b790d8f7..71522bcd7d5 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -29,7 +29,6 @@ #ifndef LL_LLPLUGINCLASSMEDIA_H #define LL_LLPLUGINCLASSMEDIA_H -#include "llgltypes.h" #include "llpluginprocessparent.h" #include "llrect.h" #include "llpluginclassmediaowner.h" @@ -201,6 +200,12 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; } + void undo(); + bool canUndo() const { return mCanUndo; }; + + void redo(); + bool canRedo() const { return mCanRedo; }; + void cut(); bool canCut() const { return mCanCut; }; @@ -210,6 +215,14 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner void paste(); bool canPaste() const { return mCanPaste; }; + void doDelete(); + bool canDoDelete() const { return mCanDoDelete; }; + + void selectAll(); + bool canSelectAll() const { return mCanSelectAll; }; + + void showPageSource(); + // These can be called before init(), and they will be queued and sent before the media init message. void setUserDataPath(const std::string &user_data_path_cache, const std::string &username, const std::string &user_data_path_cef_log); void setLanguageCode(const std::string &language_code); @@ -351,9 +364,9 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true S32 mRequestedTextureDepth; - LLGLenum mRequestedTextureInternalFormat; - LLGLenum mRequestedTextureFormat; - LLGLenum mRequestedTextureType; + U32 mRequestedTextureInternalFormat; + U32 mRequestedTextureFormat; + U32 mRequestedTextureType; bool mRequestedTextureSwapBytes; bool mRequestedTextureCoordsOpenGL; @@ -419,9 +432,13 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner F64 mSleepTime; + bool mCanUndo; + bool mCanRedo; bool mCanCut; bool mCanCopy; bool mCanPaste; + bool mCanDoDelete; + bool mCanSelectAll; std::string mMediaName; std::string mMediaDescription; diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 0ea6495eaca..4df3e306cbf 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -30,18 +30,6 @@ add_executable(SLPlugin ${SLPlugin_SOURCE_FILES} ) -if (WINDOWS) -set_target_properties(SLPlugin - PROPERTIES - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\"" - ) -else () -set_target_properties(SLPlugin - PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist - ) -endif () - target_link_libraries(SLPlugin llplugin llmessage @@ -49,7 +37,20 @@ target_link_libraries(SLPlugin ll::pluginlibraries ) -if (DARWIN) +if (WINDOWS) + set_target_properties(SLPlugin + PROPERTIES + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\"" + ) +elseif (DARWIN) + set_target_properties(SLPlugin + PROPERTIES + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_RPATH "@executable_path/../../../../Frameworks;@executable_path/../Frameworks;@executable_path/../Frameworks/plugins" + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist + XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym" + ) + # Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later) add_custom_command( TARGET SLPlugin POST_BUILD @@ -58,7 +59,7 @@ if (DARWIN) -p ${CMAKE_CURRENT_BINARY_DIR}/$,$,>/SLPlugin.app/Contents/Resources ) -endif (DARWIN) +endif () if (LL_TESTS) ll_deploy_sharedlibs_command(SLPlugin) diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index bfcd84a43df..81ebe631c5a 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1319,7 +1319,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do { //Build a joint for the resolver to work with char str[64]={0}; - sprintf(str,"./%s",(*jointIt).first.c_str() ); + snprintf(str, sizeof(str), "./%s",(*jointIt).first.c_str() ); //LL_WARNS()<<"Joint "<< str <& object, const char* key, const LLVector2& default_value); static F32 floatFromJson(const std::map& object, const char* key, const F32 default_value); diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 5f046642673..d37b16ce0ca 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -56,9 +56,9 @@ FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL; -LLFontManager *gFontManagerp = NULL; +LLFontManager *gFontManagerp = nullptr; -FT_Library gFTLibrary = NULL; +FT_Library gFTLibrary = nullptr; //static void LLFontManager::initClass() @@ -73,7 +73,7 @@ void LLFontManager::initClass() void LLFontManager::cleanupClass() { delete gFontManagerp; - gFontManagerp = NULL; + gFontManagerp = nullptr; } LLFontManager::LLFontManager() @@ -101,6 +101,7 @@ LLFontManager::LLFontManager() LLFontManager::~LLFontManager() { FT_Done_FreeType(gFTLibrary); + unloadAllFonts(); } @@ -139,12 +140,8 @@ LLFontFreetype::LLFontFreetype() mAscender(0.f), mDescender(0.f), mLineHeight(0.f), -#ifdef LL_WINDOWS - pFileStream(NULL), - pFtStream(NULL), -#endif mIsFallback(false), - mFTFace(NULL), + mFTFace(nullptr), mRenderGlyphCount(0), mStyle(0), mPointSize(0) @@ -157,35 +154,16 @@ LLFontFreetype::~LLFontFreetype() // Clean up freetype libs. if (mFTFace) FT_Done_Face(mFTFace); - mFTFace = NULL; + mFTFace = nullptr; // Delete glyph info std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer()); mCharGlyphInfoMap.clear(); -#ifdef LL_WINDOWS - delete pFileStream; // closed by FT_Done_Face - delete pFtStream; -#endif delete mFontBitmapCachep; // mFallbackFonts cleaned up by LLPointer destructor } -#ifdef LL_WINDOWS -unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) { - if (count <= 0) return count; - llifstream *file_stream = static_cast(stream->descriptor.pointer); - file_stream->seekg(offset, std::ios::beg); - file_stream->read((char*)buffer, count); - return (unsigned long)file_stream->gcount(); -} - -void ft_close_cb(FT_Stream stream) { - llifstream *file_stream = static_cast(stream->descriptor.pointer); - file_stream->close(); -} -#endif - bool LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n) { // Don't leak face objects. This is also needed to deal with @@ -193,26 +171,21 @@ bool LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if (mFTFace) { FT_Done_Face(mFTFace); - mFTFace = NULL; + mFTFace = nullptr; } - int error; -#ifdef LL_WINDOWS - error = ftOpenFace(filename, face_n); -#else - error = FT_New_Face( gFTLibrary, - filename.c_str(), - 0, - &mFTFace); -#endif + FT_Open_Args openArgs; + memset( &openArgs, 0, sizeof( openArgs ) ); + openArgs.memory_base = gFontManagerp->loadFont( filename, openArgs.memory_size ); + + if( !openArgs.memory_base ) + return false; + + openArgs.flags = FT_OPEN_MEMORY; + int error = FT_Open_Face( gFTLibrary, &openArgs, 0, &mFTFace ); if (error) - { -#ifdef LL_WINDOWS - clearFontStreams(); -#endif return false; - } mIsFallback = is_fallback; F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi @@ -227,10 +200,8 @@ bool LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v { // Clean up freetype libs. FT_Done_Face(mFTFace); -#ifdef LL_WINDOWS - clearFontStreams(); -#endif - mFTFace = NULL; + + mFTFace = nullptr; return false; } @@ -286,73 +257,30 @@ S32 LLFontFreetype::getNumFaces(const std::string& filename) if (mFTFace) { FT_Done_Face(mFTFace); - mFTFace = NULL; + mFTFace = nullptr; } S32 num_faces = 1; -#ifdef LL_WINDOWS - int error = ftOpenFace(filename, 0); + FT_Open_Args openArgs; + memset( &openArgs, 0, sizeof( openArgs ) ); + openArgs.memory_base = gFontManagerp->loadFont( filename, openArgs.memory_size ); + if( !openArgs.memory_base ) + return 0; + openArgs.flags = FT_OPEN_MEMORY; + int error = FT_Open_Face( gFTLibrary, &openArgs, 0, &mFTFace ); if (error) - { return 0; - } else - { num_faces = mFTFace->num_faces; - } FT_Done_Face(mFTFace); - clearFontStreams(); - mFTFace = NULL; -#endif + mFTFace = nullptr; return num_faces; } -#ifdef LL_WINDOWS -S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n) -{ - S32 error = -1; - pFileStream = new llifstream(filename, std::ios::binary); - if (pFileStream->is_open()) - { - std::streampos beg = pFileStream->tellg(); - pFileStream->seekg(0, std::ios::end); - std::streampos end = pFileStream->tellg(); - std::size_t file_size = end - beg; - pFileStream->seekg(0, std::ios::beg); - - pFtStream = new LLFT_Stream(); - pFtStream->base = 0; - pFtStream->pos = 0; - pFtStream->size = static_cast(file_size); - pFtStream->descriptor.pointer = pFileStream; - pFtStream->read = ft_read_cb; - pFtStream->close = ft_close_cb; - - FT_Open_Args args; - args.flags = FT_OPEN_STREAM; - args.stream = (FT_StreamRec*)pFtStream; - error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace); - } - return error; -} - -void LLFontFreetype::clearFontStreams() -{ - if (pFileStream) - { - pFileStream->close(); - } - delete pFileStream; - delete pFtStream; - pFileStream = NULL; - pFtStream = NULL; -} -#endif - void LLFontFreetype::addFallbackFont(const LLPointer& fallback_font, const char_functor_t& functor) { @@ -376,7 +304,7 @@ F32 LLFontFreetype::getDescenderHeight() const F32 LLFontFreetype::getXAdvance(llwchar wch) const { - if (mFTFace == NULL) + if (mFTFace == nullptr) return 0.0; // Return existing info only if it is current @@ -400,7 +328,7 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const { - if (mFTFace == NULL) + if (mFTFace == nullptr) return 0.0; return glyph->mXAdvance; @@ -408,7 +336,7 @@ F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const { - if (mFTFace == NULL) + if (mFTFace == nullptr) return 0.0; //llassert(!mIsFallback); @@ -427,7 +355,7 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const { - if (mFTFace == NULL) + if (mFTFace == nullptr) return 0.0; U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; @@ -450,7 +378,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type { if (!mFTFace) { - return NULL; + return nullptr; } llassert(!mIsFallback); @@ -541,14 +469,14 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type { return addGlyphFromFont(this, wch, glyph_index, glyph_type); } - return NULL; + return nullptr; } LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType requested_glyph_type) const { LL_PROFILE_ZONE_SCOPED; - if (mFTFace == NULL) - return NULL; + if (mFTFace == nullptr) + return nullptr; llassert(!mIsFallback); fontp->renderGlyph(requested_glyph_type, glyph_index, wch); @@ -600,7 +528,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l { U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer; S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch; - U8 *tmp_graydata = NULL; + U8 *tmp_graydata = nullptr; if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) @@ -704,7 +632,7 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const { - if (mFTFace == NULL) + if (mFTFace == nullptr) return; FT_Int32 load_flags = FT_LOAD_FORCE_AUTOHINT; @@ -918,3 +846,58 @@ void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 } } + +namespace ll +{ + namespace fonts + { + class LoadedFont + { + public: + LoadedFont( std::string aName , std::string const &aAddress, std::size_t aSize ) + : mAddress( aAddress ) + { + mName = aName; + mSize = aSize; + mRefs = 1; + } + std::string mName; + std::string mAddress; + std::size_t mSize; + U32 mRefs; + }; + } +} + +U8 const* LLFontManager::loadFont( std::string const &aFilename, long &a_Size) +{ + a_Size = 0; + std::map< std::string, std::shared_ptr >::iterator itr = m_LoadedFonts.find( aFilename ); + if( itr != m_LoadedFonts.end() ) + { + ++itr->second->mRefs; + // A possible overflow cannot happen here, as it is asserted that the size is less than std::numeric_limits::max() a few lines below. + a_Size = static_cast(itr->second->mSize); + return reinterpret_cast(itr->second->mAddress.c_str()); + } + + auto strContent = LLFile::getContents(aFilename); + + if( strContent.empty() ) + return nullptr; + + // For fontconfig a type of long is required, std::string::size() returns size_t. I think it is safe to limit this to 2GiB and not support fonts that huge (can that even be a thing?) + llassert_always( strContent.size() < std::numeric_limits::max() ); + + a_Size = static_cast(strContent.size()); + + auto pCache = std::make_shared( aFilename, strContent, a_Size ); + itr = m_LoadedFonts.insert( std::make_pair( aFilename, pCache ) ).first; + + return reinterpret_cast(itr->second->mAddress.c_str()); +} + +void LLFontManager::unloadAllFonts() +{ + m_LoadedFonts.clear(); +} diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index 783bf4a4b30..a9b3a944ee2 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -43,15 +43,28 @@ typedef struct FT_FaceRec_* LLFT_Face; struct FT_StreamRec_; typedef struct FT_StreamRec_ LLFT_Stream; +namespace ll +{ + namespace fonts + { + class LoadedFont; + } +} + class LLFontManager { public: static void initClass(); static void cleanupClass(); + U8 const *loadFont( std::string const &aFilename, long &a_Size ); + private: LLFontManager(); ~LLFontManager(); + + void unloadAllFonts(); + std::map< std::string, std::shared_ptr > m_LoadedFonts; }; struct LLFontGlyphInfo @@ -90,11 +103,6 @@ class LLFontFreetype : public LLRefCount S32 getNumFaces(const std::string& filename); -#ifdef LL_WINDOWS - S32 ftOpenFace(const std::string& filename, S32 face_n); - void clearFontStreams(); -#endif - typedef std::function char_functor_t; void addFallbackFont(const LLPointer& fallback_font, const char_functor_t& functor = nullptr); @@ -170,11 +178,6 @@ class LLFontFreetype : public LLRefCount LLFT_Face mFTFace; -#ifdef LL_WINDOWS - llifstream *pFileStream; - LLFT_Stream *pFtStream; -#endif - bool mIsFallback; typedef std::pair, char_functor_t> fallback_font_t; typedef std::vector fallback_font_vector_t; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 0be27b89757..d13b98e2747 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -1123,17 +1123,6 @@ bool LLGLManager::initGL() if (mGLVersion >= 2.f) { parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor); - -#if 0 && LL_DARWIN - // TODO maybe switch to using a core profile for GL 3.2? - // https://stackoverflow.com/a/19868861 - //never use GLSL greater than 1.20 on OSX - if (mGLSLVersionMajor > 1 || mGLSLVersionMinor > 30) - { - mGLSLVersionMajor = 1; - mGLSLVersionMinor = 30; - } -#endif } if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures) @@ -1247,7 +1236,7 @@ bool LLGLManager::initGL() // there's some implementation that reports a crazy value mMaxUniformBlockSize = llmin(mMaxUniformBlockSize, 65536); - if (mGLVersion >= 4.59f) + if (mHasAnisotropic) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxAnisotropy); } @@ -1411,6 +1400,11 @@ void LLGLManager::initExtensions() mHasCubeMapArray = mGLVersion >= 3.99f; mHasTransformFeedback = mGLVersion >= 3.99f; mHasDebugOutput = mGLVersion >= 4.29f; + mHasAnisotropic = mGLVersion >= 4.59f; + if(!mHasAnisotropic && gGLHExts.mSysExts) + { + mHasAnisotropic = ExtensionExists("GL_EXT_texture_filter_anisotropic", gGLHExts.mSysExts); + } // Misc glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange); @@ -2728,7 +2722,7 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) if(cplane[2] < 0) cplane *= -1; - glm::mat4 suffix; + glm::mat4 suffix = glm::identity(); suffix = glm::row(suffix, 2, cplane); glm::mat4 newP = suffix * P; gGL.matrixMode(LLRender::MM_PROJECTION); diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 3735a991090..9cd5dc8145b 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -421,8 +421,11 @@ bool LLGLSLShader::createShader() llassert_always(!mShaderFiles.empty()); #if LL_DARWIN - // work-around missing mix(vec3,vec3,bvec3) - mDefines["OLD_SELECT"] = "1"; + if(!gGLManager.mIsApple) + { + // work-around missing mix(vec3,vec3,bvec3) + mDefines["OLD_SELECT"] = "1"; + } #endif mShaderHash = hash(); @@ -543,7 +546,7 @@ bool LLGLSLShader::createShader() } } -#ifdef LL_PROFILER_ENABLE_RENDER_DOC +#if LL_PROFILER_ENABLE_RENDER_DOC setLabel(mName.c_str()); #endif @@ -2078,7 +2081,7 @@ LLUUID LLGLSLShader::hash() return hash_obj.digest(); } -#ifdef LL_PROFILER_ENABLE_RENDER_DOC +#if LL_PROFILER_ENABLE_RENDER_DOC void LLGLSLShader::setLabel(const char* label) { LL_LABEL_OBJECT_GL(GL_PROGRAM, mProgramObject, strlen(label), label); } diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 873ab0cff59..4702a27cc54 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -361,7 +361,7 @@ class LLGLSLShader // hacky flag used for optimization in LLDrawPoolAlpha bool mCanBindFast = false; -#ifdef LL_PROFILER_ENABLE_RENDER_DOC +#if LL_PROFILER_ENABLE_RENDER_DOC void setLabel(const char* label); #endif @@ -381,7 +381,7 @@ extern LLGLSLShader gSolidColorProgram; //Alpha mask shader (declared here so llappearance can access properly) extern LLGLSLShader gAlphaMaskProgram; -#ifdef LL_PROFILER_ENABLE_RENDER_DOC +#if LL_PROFILER_ENABLE_RENDER_DOC #define LL_SET_SHADER_LABEL(shader) shader.setLabel(#shader) #else #define LL_SET_SHADER_LABEL(shader, label) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 1db36d91f9e..97ea6f67bd8 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -338,6 +338,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac case GL_DEPTH_COMPONENT: return 24; case GL_DEPTH_COMPONENT24: return 24; + case GL_RGBA16: return 64; case GL_R16F: return 16; case GL_RG16F: return 32; case GL_RGB16F: return 48; @@ -1096,6 +1097,8 @@ void sub_image_lines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 w // full width texture, do 32 lines at a time for (U32 y_pos = y_offset; y_pos < y_offset_end; y_pos += batch_size) { + // If this keeps crashing, pass down data_size, looks like it is using + // imageraw->getData(); for data, but goes way over allocated size limit glTexSubImage2D(target, miplevel, x_offset, y_pos, width, batch_size, pixformat, pixtype, src); src += line_width * batch_size; } @@ -1105,6 +1108,8 @@ void sub_image_lines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 w // partial width or strange height for (U32 y_pos = y_offset; y_pos < y_offset_end; y_pos += 1) { + // If this keeps crashing, pass down data_size, looks like it is using + // imageraw->getData(); for data, but goes way over allocated size limit glTexSubImage2D(target, miplevel, x_offset, y_pos, width, 1, pixformat, pixtype, src); src += line_width; } @@ -1545,6 +1550,7 @@ bool LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S llassert(mCurrentDiscardLevel >= 0); discard_level = mCurrentDiscardLevel; } + discard_level = llmin(discard_level, MAX_DISCARD_LEVEL); // Actual image width/height = raw image width/height * 2^discard_level S32 raw_w = imageraw->getWidth() ; @@ -1643,6 +1649,7 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_ discard_level = mCurrentDiscardLevel; } discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); + discard_level = llmin(discard_level, MAX_DISCARD_LEVEL); if (main_thread // <--- always force creation of new_texname when not on main thread ... && !defer_copy // <--- ... or defer copy is set diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 1dc87a66cea..57be8570afb 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -118,7 +118,7 @@ static const GLenum sGLBlendFactor[] = LLTexUnit::LLTexUnit(S32 index) : mCurrTexType(TT_NONE), - mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), + mCurrTexture(0), mHasMipMaps(false), mIndex(index) { @@ -207,6 +207,12 @@ void LLTexUnit::bindFast(LLTexture* texture) } glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); mHasMipMaps = gl_tex->mHasMipMaps; + if (gl_tex->mTexOptionsDirty) + { + gl_tex->mTexOptionsDirty = false; + setTextureAddressModeFast(gl_tex->mAddressMode, gl_tex->getTarget()); + setTextureFilteringOptionFast(gl_tex->mFilterOption, gl_tex->getTarget()); + } } bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) @@ -461,11 +467,16 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) activate(); - glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); - glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]); - if (mCurrTexType == TT_CUBE_MAP) + setTextureAddressModeFast(mode, mCurrTexType); +} + +void LLTexUnit::setTextureAddressModeFast(eTextureAddressMode mode, eTextureType tex_type) +{ + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]); + if (tex_type == TT_CUBE_MAP || tex_type == TT_CUBE_MAP_ARRAY || tex_type == TT_TEXTURE_3D) { - glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); } } @@ -475,51 +486,56 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio gGL.flush(); + setTextureFilteringOptionFast(option, mCurrTexType); +} + +void LLTexUnit::setTextureFilteringOptionFast(LLTexUnit::eTextureFilterOptions option, eTextureType tex_type) +{ if (option == TFO_POINT) { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_MAG_FILTER, GL_NEAREST); } else { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (option >= TFO_TRILINEAR && mHasMipMaps) { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else if (option >= TFO_BILINEAR) { if (mHasMipMaps) { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); } else { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_MIN_FILTER, GL_LINEAR); } } else { if (mHasMipMaps) { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); } else { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(sGLTextureType[tex_type], GL_TEXTURE_MIN_FILTER, GL_NEAREST); } } - if (gGLManager.mGLVersion >= 4.59f) + if (gGLManager.mHasAnisotropic) { if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); + glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); } else { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); + glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, 1.f); } } } @@ -600,26 +616,6 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) } } -void LLTexUnit::setColorScale(S32 scale) -{ - if (mCurrColorScale != scale || gGL.mDirty) - { - mCurrColorScale = scale; - gGL.flush(); - glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); - } -} - -void LLTexUnit::setAlphaScale(S32 scale) -{ - if (mCurrAlphaScale != scale || gGL.mDirty) - { - mCurrAlphaScale = scale; - gGL.flush(); - glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); - } -} - // Useful for debugging that you've manually assigned a texture operation to the correct // texture unit based on the currently set active texture in opengl. void LLTexUnit::debugTextureUnit(void) @@ -1283,9 +1279,7 @@ void LLRender::translateUI(F32 x, F32 y, F32 z) LL_ERRS() << "Need to push a UI translation frame before offsetting" << LL_ENDL; } - mUIOffset.back().mV[0] += x; - mUIOffset.back().mV[1] += y; - mUIOffset.back().mV[2] += z; + mUIOffset.back().add(LLVector4a(x, y, z)); } void LLRender::scaleUI(F32 x, F32 y, F32 z) @@ -1295,14 +1289,14 @@ void LLRender::scaleUI(F32 x, F32 y, F32 z) LL_ERRS() << "Need to push a UI transformation frame before scaling." << LL_ENDL; } - mUIScale.back().scaleVec(LLVector3(x,y,z)); + mUIScale.back().mul(LLVector4a(x, y, z)); } void LLRender::pushUIMatrix() { if (mUIOffset.empty()) { - mUIOffset.emplace_back(0.f,0.f,0.f); + mUIOffset.emplace_back(0.f); } else { @@ -1311,7 +1305,7 @@ void LLRender::pushUIMatrix() if (mUIScale.empty()) { - mUIScale.emplace_back(1.f,1.f,1.f); + mUIScale.emplace_back(1.f); } else { @@ -1333,18 +1327,20 @@ LLVector3 LLRender::getUITranslation() { if (mUIOffset.empty()) { - return LLVector3(0,0,0); + return LLVector3::zero; } - return mUIOffset.back(); + + return LLVector3(mUIOffset.back().getF32ptr()); } LLVector3 LLRender::getUIScale() { if (mUIScale.empty()) { - return LLVector3(1,1,1); + return LLVector3::all_one; } - return mUIScale.back(); + + return LLVector3(mUIScale.back().getF32ptr()); } @@ -1354,8 +1350,9 @@ void LLRender::loadUIIdentity() { LL_ERRS() << "Need to push UI translation frame before clearing offset." << LL_ENDL; } - mUIOffset.back().setVec(0,0,0); - mUIScale.back().setVec(1,1,1); + + mUIOffset.back().clear(); + mUIScale.back().splat(1); } void LLRender::setColorMask(bool writeColor, bool writeAlpha) @@ -1783,8 +1780,10 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) } else { - LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back()); - mVerticesp[mCount].set(vert.mV[VX], vert.mV[VY], vert.mV[VZ]); + LLVector4a vert(x, y, z); + vert.add(mUIOffset.back()); + vert.mul(mUIScale.back()); + mVerticesp[mCount] = vert; } mCount++; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7b6bd4198b7..0801c12fb4c 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -43,6 +43,7 @@ #include "llglheaders.h" #include "llmatrix4a.h" #include "glm/mat4x4.hpp" +#include #include #include @@ -207,11 +208,15 @@ class LLTexUnit // Warning: this stays set for the bound texture forever, // make sure you want to permanently change the address mode for the bound texture. void setTextureAddressMode(eTextureAddressMode mode); + // MUST already be active and bound + void setTextureAddressModeFast(eTextureAddressMode mode, eTextureType tex_type); // Sets the filtering options used to sample the texture // Warning: this stays set for the bound texture forever, // make sure you want to permanently change the filtering for the bound texture. void setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option); + // MUST already be active and bound + void setTextureFilteringOptionFast(LLTexUnit::eTextureFilterOptions option, eTextureType tex_type); static U32 getInternalType(eTextureType type); @@ -227,13 +232,9 @@ class LLTexUnit S32 mIndex; U32 mCurrTexture; eTextureType mCurrTexType; - S32 mCurrColorScale; - S32 mCurrAlphaScale; bool mHasMipMaps; void debugTextureUnit(void); - void setColorScale(S32 scale); - void setAlphaScale(S32 scale); GLint getTextureSource(eTextureBlendSrc src); GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false); }; @@ -526,8 +527,8 @@ class LLRender eBlendFactor mCurrBlendAlphaSFactor; eBlendFactor mCurrBlendAlphaDFactor; - std::vector mUIOffset; - std::vector mUIScale; + std::vector > mUIOffset; + std::vector > mUIScale; }; extern F32 gGLModelView[16]; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 38bc5ff3315..0b0d69812f0 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -492,22 +492,6 @@ U32 LLRenderTarget::getNumTextures() const void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options) { gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index), filter_options == LLTexUnit::TFO_TRILINEAR || filter_options == LLTexUnit::TFO_ANISOTROPIC); - - bool isSRGB = false; - llassert(mInternalFormat.size() > index); - switch (mInternalFormat[index]) - { - case GL_SRGB: - case GL_SRGB8: - case GL_SRGB_ALPHA: - case GL_SRGB8_ALPHA8: - isSRGB = true; - break; - - default: - break; - } - gGL.getTexUnit(channel)->setTextureFilteringOption(filter_options); } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 4807c122263..e9bbdeead52 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -458,7 +458,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev // endsure work-around for missing GLSL funcs gets propogated to feature shader files (e.g. srgbF.glsl) #if LL_DARWIN - if (defines) + if (!gGLManager.mIsApple && defines) { (*defines)["OLD_SELECT"] = "1"; } @@ -989,16 +989,17 @@ bool LLShaderMgr::validateProgramObject(GLuint obj) return success; } -void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version) +void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version, bool second_instance) { - LL_INFOS() << "Initializing shader cache" << LL_ENDL; + LL_PROFILE_ZONE_SCOPED; + LL_INFOS("ShaderMgr") << "Initializing shader cache" << LL_ENDL; mShaderCacheEnabled = gGLManager.mGLVersion >= 4.09 && enabled; - if(!mShaderCacheEnabled || mShaderCacheInitialized) + if(!mShaderCacheEnabled || mShaderCacheVersion.notNull()) return; - mShaderCacheInitialized = true; + mShaderCacheVersion = current_cache_version; mShaderCacheDir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache"); LLFile::mkdir(mShaderCacheDir); @@ -1007,16 +1008,19 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd"); if (gDirUtilp->fileExists(meta_out_path)) { - LL_INFOS() << "Loading shader cache metadata" << LL_ENDL; + LL_PROFILE_ZONE_NAMED("shader_cache"); + LL_INFOS("ShaderMgr") << "Loading shader cache metadata" << LL_ENDL; - llifstream instream(meta_out_path); + llifstream instream(meta_out_path, std::ifstream::in | std::ifstream::binary); LLSD in_data; - LLSDSerialize::fromNotation(in_data, instream, LLSDSerialize::SIZE_UNLIMITED); + // todo: this is likely very expensive to parse, should use binary + LLSDSerialize::fromBinary(in_data, instream, LLSDSerialize::SIZE_UNLIMITED); instream.close(); - if (old_cache_version == current_cache_version) + if (old_cache_version == current_cache_version + && in_data["version"].asUUID() == current_cache_version) { - for (const auto& data_pair : llsd::inMap(in_data)) + for (const auto& data_pair : llsd::inMap(in_data["shaders"])) { ProgramBinaryData binary_info = ProgramBinaryData(); binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger(); @@ -1025,11 +1029,15 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info); } } - else + else if (!second_instance) { - LL_INFOS() << "Shader cache version mismatch detected. Purging." << LL_ENDL; + LL_INFOS("ShaderMgr") << "Shader cache version mismatch detected. Purging." << LL_ENDL; clearShaderCache(); } + else + { + LL_INFOS("ShaderMgr") << "Shader cache version mismatch detected." << LL_ENDL; + } } } } @@ -1037,19 +1045,32 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, void LLShaderMgr::clearShaderCache() { std::string shader_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache"); - LL_INFOS() << "Removing shader cache at " << shader_cache << LL_ENDL; + LL_INFOS("ShaderMgr") << "Removing shader cache at " << shader_cache << LL_ENDL; const std::string mask = "*"; gDirUtilp->deleteFilesInDir(shader_cache, mask); + LLFile::rmdir(shader_cache); mShaderBinaryCache.clear(); } void LLShaderMgr::persistShaderCacheMetadata() { if(!mShaderCacheEnabled) return; + if (mShaderCacheVersion.isNull()) + { + LL_WARNS("ShaderMgr") << "Attempted to save shader cache with no version set" << LL_ENDL; + return; + } - LL_INFOS() << "Persisting shader cache metadata to disk" << LL_ENDL; + LL_INFOS("ShaderMgr") << "Persisting shader cache metadata to disk" << LL_ENDL; - LLSD out = LLSD::emptyMap(); + LLSD out; + // Settings and shader cache get saved at different time, thus making + // RenderShaderCacheVersion unreliable when running multiple viewer + // instances, or for cases where viewer crashes before saving settings. + // Dupplicate version to the cache itself. + out["version"] = mShaderCacheVersion; + out["shaders"] = LLSD::emptyMap(); + LLSD &shaders = out["shaders"]; static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days const F32 current_time = (F32)LLTimer::getTotalSeconds(); @@ -1068,14 +1089,19 @@ void LLShaderMgr::persistShaderCacheMetadata() data["binary_format"] = LLSD::Integer(shader_metadata.mBinaryFormat); data["binary_size"] = LLSD::Integer(shader_metadata.mBinaryLength); data["last_used"] = LLSD::Real(shader_metadata.mLastUsedTime); - out[it->first.asString()] = data; + shaders[it->first.asString()] = data; ++it; } } std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd"); - llofstream outstream(meta_out_path); - LLSDSerialize::toNotation(out, outstream); + llofstream outstream(meta_out_path, std::ios_base::out | std::ios_base::binary); + if (!outstream.is_open()) + { + LL_WARNS("ShaderMgr") << "Failed to open file. Unable to save shader cache to: " << mShaderCacheDir << LL_ENDL; + return; + } + LLSDSerialize::toBinary(out, outstream); outstream.close(); } diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 46788841a5d..1b638e6e065 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -363,7 +363,7 @@ class LLShaderMgr // Implemented in the application to actually update out of date uniforms for a particular shader virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual - void initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version); + void initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version, bool second_instance); void clearShaderCache(); void persistShaderCacheMetadata(); @@ -387,7 +387,7 @@ class LLShaderMgr F32 mLastUsedTime = 0.0; }; std::map mShaderBinaryCache; - bool mShaderCacheInitialized = false; + LLUUID mShaderCacheVersion; bool mShaderCacheEnabled = false; std::string mShaderCacheDir; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1f0c424188f..d59ddd0fecb 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -787,12 +787,6 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto gGL.syncMatrices(); - U32 mask = LLVertexBuffer::MAP_VERTEX; - if (tc) - { - mask = mask | LLVertexBuffer::MAP_TEXCOORD0; - } - unbind(); gGL.begin(mode); @@ -885,7 +879,7 @@ bool LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of return true; } -#ifdef LL_PROFILER_ENABLE_RENDER_DOC +#if LL_PROFILER_ENABLE_RENDER_DOC void LLVertexBuffer::setLabel(const char* label) { LL_LABEL_OBJECT_GL(GL_BUFFER, mGLBuffer, strlen(label), label); } diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 375ad76fb84..faaa6ba0f0e 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -279,7 +279,7 @@ class LLVertexBuffer final : public LLRefCount //for debugging, validate data in given range is valid bool validateRange(U32 start, U32 end, U32 count, U32 offset) const; - #ifdef LL_PROFILER_ENABLE_RENDER_DOC + #if LL_PROFILER_ENABLE_RENDER_DOC void setLabel(const char* label); #endif @@ -340,7 +340,7 @@ class LLVertexBuffer final : public LLRefCount static U32 sVertexCount; }; -#ifdef LL_PROFILER_ENABLE_RENDER_DOC +#if LL_PROFILER_ENABLE_RENDER_DOC #define LL_LABEL_VERTEX_BUFFER(buf, name) buf->setLabel(name) #else #define LL_LABEL_VERTEX_BUFFER(buf, name) diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 495ba2f40fd..1a64c2699dd 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -303,8 +303,11 @@ void LLAccordionCtrl::ctrlSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S3 return; LLRect panel_rect = panel->getRect(); panel_rect.setLeftTopAndSize( left, top, width, height); - panel->reshape( width, height, 1); - panel->setRect(panel_rect); + if (panel->getRect() != panel_rect) + { + panel->reshape( width, height, 1); + panel->setRect(panel_rect); + } } void LLAccordionCtrl::ctrlShiftVertical(LLView* panel, S32 delta) @@ -494,6 +497,7 @@ void LLAccordionCtrl::arrangeMultiple() void LLAccordionCtrl::arrange() { + LL_PROFILE_ZONE_SCOPED; updateNoTabsHelpTextVisibility(); if (mAccordionTabs.empty()) diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index ac665250306..bdf93348bb9 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -248,10 +248,22 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw() void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::reshape(S32 width, S32 height, bool called_from_parent /* = true */) { S32 header_height = mHeaderTextbox->getTextPixelHeight(); + LLRect old_header_rect = mHeaderTextbox->getRect(); LLRect textboxRect(HEADER_TEXT_LEFT_OFFSET, (height + header_height) / 2, width, (height - header_height) / 2); - mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight()); - mHeaderTextbox->setRect(textboxRect); + if (old_header_rect.getHeight() != textboxRect.getHeight() + || old_header_rect.mLeft != textboxRect.mLeft + || old_header_rect.mTop != textboxRect.mTop + || old_header_rect.getWidth() > textboxRect.getWidth() // reducing header's width + || (old_header_rect.getWidth() < textboxRect.getWidth() && old_header_rect.getWidth() < mHeaderTextbox->getTextPixelWidth())) + { + // Expensive text reflow + // Update if position or height changes + // Update if width reduces + // But do not update if text already fits and width increases (arguably LLTextBox::reshape should be smarter, not Accordion) + mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight()); + mHeaderTextbox->setRect(textboxRect); + } if (mHeaderTextbox->getTextPixelWidth() > mHeaderTextbox->getRect().getWidth()) { @@ -416,8 +428,11 @@ void LLAccordionCtrlTab::reshape(S32 width, S32 height, bool called_from_parent LLRect headerRect; headerRect.setLeftTopAndSize(0, height, width, HEADER_HEIGHT); - mHeader->setRect(headerRect); - mHeader->reshape(headerRect.getWidth(), headerRect.getHeight()); + if (mHeader->getRect() != headerRect) + { + mHeader->setRect(headerRect); + mHeader->reshape(headerRect.getWidth(), headerRect.getHeight()); + } if (!mDisplayChildren) return; @@ -932,7 +947,7 @@ void LLAccordionCtrlTab::adjustContainerPanel(const LLRect& child_rect) show_hide_scrollbar(child_rect); updateLayout(child_rect); } - else + else if (mContainerPanel->getRect() != child_rect) { mContainerPanel->reshape(child_rect.getWidth(), child_rect.getHeight()); mContainerPanel->setRect(child_rect); diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index f3876ef6957..17e583b868c 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -251,11 +251,26 @@ void LLComboBox::resetDirty() } } -bool LLComboBox::itemExists(const std::string& name) +bool LLComboBox::itemExists(const std::string& name) const { return mList->getItemByLabel(name); } +bool LLComboBox::valueExists(const std::string& value) const +{ + return mList->getItemByValue(value); +} + +LLScrollListItem* LLComboBox::findItemByValue(const std::string& value) const +{ + return mList->getItemByValue(value); +} + +std::vector LLComboBox::getAllData() const +{ + return mList->getAllData(); +} + // add item "name" to menu LLScrollListItem* LLComboBox::add(const std::string& name, EAddPosition pos, bool enabled) { diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 8be3eb57e4f..be18cdba487 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -143,7 +143,10 @@ class LLComboBox LLScrollListItem* addSeparator(EAddPosition pos = ADD_BOTTOM); bool remove( S32 index ); // remove item by index, return true if found and removed void removeall() { clearRows(); } - bool itemExists(const std::string& name); + bool itemExists(const std::string& name) const; + bool valueExists(const std::string& value) const; + LLScrollListItem* findItemByValue(const std::string& value) const; + std::vector getAllData() const; void sortByName(bool ascending = true); // Sort the entries in the combobox by name diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp index 925608e47ea..16e6f0591af 100644 --- a/indra/llui/llemojidictionary.cpp +++ b/indra/llui/llemojidictionary.cpp @@ -390,14 +390,17 @@ void LLEmojiDictionary::loadEmojis() continue; } + std::string category; std::list categories = loadCategories(sd); if (categories.empty()) { - LL_WARNS() << "Skipping invalid emoji descriptor (no categories)" << LL_ENDL; - continue; + // Should already have a localization for "other symbols" + category = "other symbols"; + } + else + { + category = categories.front(); } - - std::string category = categories.front(); if (std::find(mSkipCategories.begin(), mSkipCategories.end(), category) != mSkipCategories.end()) { diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index b664065532a..db4ab8487e5 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -1510,6 +1510,7 @@ bool LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) && ( count > 0 && (hasVisibleChildren()) ))) && // show menu only if selected items are visible !hide_folder_menu) { + LL_INFOS("Inventory") << "Opening inventory menu from path: " << getPathname() << LL_ENDL; if (mCallbackRegistrar) { mCallbackRegistrar->pushScope(); diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 9ca77dbe46b..0f9fd358682 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -2106,10 +2106,14 @@ void LLFolderViewFolder::setOpen(bool openitem) { // navigateToFolder can destroy this view // delay it in case setOpen was called from click or key processing - doOnIdleOneTime([this]() - { - getViewModelItem()->navigateToFolder(); - }); + LLPointer view_model_item = mViewModelItem; + doOnIdleOneTime([view_model_item]() + { + if (view_model_item.notNull()) + { + view_model_item.get()->navigateToFolder(); + } + }); } else { diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 2bea8fb4ed2..aa5aceddfac 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -28,43 +28,26 @@ #include #include +#include #include "llkeywords.h" #include "llsdserialize.h" #include "lltexteditor.h" #include "llstl.h" +#include "llcontrol.h" + +extern LLControlGroup gSavedSettings; inline bool LLKeywordToken::isHead(const llwchar* s) const { - // strncmp is much faster than string compare - bool res = true; - const llwchar* t = mToken.c_str(); - auto len = mToken.size(); - for (S32 i=0; ifirst == "llsd-lsl-syntax-version") { @@ -258,6 +264,21 @@ void LLKeywords::processTokens() } } } + + // Pre-compile all regex patterns for tokens in mRegexTokenList + for (LLKeywordToken* regex_token : mRegexTokenList) + { + std::string start_pattern(regex_token->getToken().begin(), regex_token->getToken().end()); + try + { + regex_token->setCompiledRegex(new std::regex(start_pattern)); + } + catch (const std::regex_error& e) + { + LL_WARNS() << "Regex error in start pattern: " << e.what() << " in pattern: " << start_pattern << LL_ENDL; + } + } + LL_INFOS("SyntaxLSL") << "Finished processing tokens." << LL_ENDL; } @@ -346,8 +367,11 @@ void LLKeywords::processTokensGroup(const LLSD& tokens, std::string_view group) break; case LLKeywordToken::TT_FUNCTION: tooltip = getAttribute("return") + " " + outer_itr->first + "(" + getArguments(arguments) + ");"; - tooltip.append("\nEnergy: "); - tooltip.append(getAttribute("energy").empty() ? "0.0" : getAttribute("energy")); + if (std::stod(getAttribute("energy")) >= 0) + { + tooltip.append("\nEnergy: "); + tooltip.append(getAttribute("energy").empty() ? "0.0" : getAttribute("energy")); + } if (!getAttribute("sleep").empty()) { tooltip += ", Sleep: " + getAttribute("sleep"); @@ -482,17 +506,28 @@ LLTrace::BlockTimerStatHandle FTM_SYNTAX_COLORING("Syntax Coloring"); void LLKeywords::findSegments(std::vector* seg_list, const LLWString& wtext, LLTextEditor& editor, LLStyleConstSP style) { LL_RECORD_BLOCK_TIME(FTM_SYNTAX_COLORING); - seg_list->clear(); if( wtext.empty() ) { return; } + // Clear the segment list + seg_list->clear(); + // Reserve capacity for segments based on an estimated average of 8 characters per segment. + constexpr size_t AVERAGE_SEGMENT_LENGTH = 8; + seg_list->reserve(wtext.size() / AVERAGE_SEGMENT_LENGTH); + S32 text_len = static_cast(wtext.size()) + 1; seg_list->push_back( new LLNormalTextSegment( style, 0, text_len, editor ) ); + std::string text_to_search; + text_to_search.reserve(wtext.size()); + + bool has_regex = !mRegexTokenList.empty(); + auto& delimiters = mDelimiterTokenList; + const llwchar* base = wtext.c_str(); const llwchar* cur = base; while( *cur ) @@ -560,16 +595,148 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLW cur++; } + // Check if syntax highlighting is disabled + static LLCachedControl sDisableSyntaxHighlighting(gSavedSettings, "ScriptEditorDisableSyntaxHighlight", false); + if (sDisableSyntaxHighlighting) + { + if (*cur && *cur != '\n') + { + cur++; + } + continue; // skip processing any further syntax highlighting + } + while( *cur && *cur != '\n' ) { + // Check for regex matches first + bool regex_matched = false; + if (has_regex) + { + S32 seg_start = (S32)(cur - base); + + text_to_search.assign(wtext.begin() + seg_start, wtext.end()); + + for (LLKeywordToken* regex_token : mRegexTokenList) + { + std::regex* compiled_regex = regex_token->getCompiledRegex(); + + // If we have a pre-compiled regex, use it + if (compiled_regex) + { + std::string end_pattern(regex_token->getDelimiter().begin(), regex_token->getDelimiter().end()); + + try + { + std::smatch start_match; + + if (std::regex_search(text_to_search, start_match, *compiled_regex) && !start_match.empty()) + { + if (start_match.position() == 0) // Match starts at current position + { + // Calculate segment boundaries for start pattern + S32 start_match_length = static_cast(start_match.str().length()); + S32 start_seg_end = seg_start + start_match_length; + + if (end_pattern.empty()) + { + // If no end pattern is provided, treat the entire regex match as a single segment + // Move cursor past the matched segment + cur = base + start_seg_end; + + // Insert the matched segment + insertSegments(wtext, *seg_list, regex_token, text_len, seg_start, start_seg_end, style, editor); + } + else + { // TODO: better optimization for this part + + // Look for the end pattern after the start pattern + std::string remaining_text = text_to_search.substr(start_match_length); + + // Process end pattern - replace any capture group references + std::string actual_end_pattern = end_pattern; + + // Handle capture groups in the end pattern (replace \1, \2, etc. with their matched content) + for (size_t i = 1; i < start_match.size(); ++i) + { + std::string capture = start_match[i].str(); + std::string placeholder = "\\" + std::to_string(i); + + // Replace all occurrences of the placeholder with the captured content + size_t pos = 0; + while ((pos = actual_end_pattern.find(placeholder, pos)) != std::string::npos) + { + actual_end_pattern.replace(pos, placeholder.length(), capture); + pos += capture.length(); + } + } + + try + { + std::regex end_regex_pattern(actual_end_pattern); + std::smatch end_match; + + S32 seg_end = start_seg_end; + + if (std::regex_search(remaining_text, end_match, end_regex_pattern) && !end_match.empty()) + { + // Calculate position of end match relative to the original text + S32 end_match_position = static_cast(end_match.position()); + S32 end_match_length = static_cast(end_match.str().length()); + + // Calculate the total length including both patterns and text between + seg_end += end_match_position + end_match_length; + } + else + { + // End pattern not found, treat everything up to EOF as the segment + seg_end += static_cast(remaining_text.length()); + } + + // Move cursor past the entire matched segment (start + content + end) + cur = base + seg_end; + + // Insert the matched segment + insertSegments(wtext, *seg_list, regex_token, text_len, seg_start, seg_end, style, editor); + } + catch (const std::regex_error& e) + { + LL_WARNS() << "Regex error in end pattern: " << e.what() << " in pattern: " << actual_end_pattern << LL_ENDL; + // Fall back to treating the start match as the entire segment + cur = base + start_seg_end; + insertSegments(wtext, *seg_list, regex_token, text_len, seg_start, start_seg_end, style, editor); + } + } + + regex_matched = true; + break; + } + } + } + catch (const std::regex_error& e) + { + LL_WARNS() << "Error using compiled regex: " << e.what() << LL_ENDL; + } + } + else + { + // Skip tokens that aren't pre-compiled + LL_WARNS() << "Skipping regex token due to missing pre-compiled pattern: " + << wstring_to_utf8str(regex_token->getToken()) << LL_ENDL; + } + } + + if (regex_matched) + { + continue; + } + } + // Check against delimiters { S32 seg_start = 0; LLKeywordToken* cur_delimiter = NULL; - for (token_list_t::iterator iter = mDelimiterTokenList.begin(); - iter != mDelimiterTokenList.end(); ++iter) + for (auto* delimiter : delimiters) { - LLKeywordToken* delimiter = *iter; if( delimiter->isHead( cur ) ) { cur_delimiter = delimiter; @@ -586,7 +753,7 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLW cur += cur_delimiter->getLengthHead(); LLKeywordToken::ETokenType type = cur_delimiter->getType(); - if( type == LLKeywordToken::TT_TWO_SIDED_DELIMITER || type == LLKeywordToken::TT_DOUBLE_QUOTATION_MARKS ) + if(type == LLKeywordToken::TT_TWO_SIDED_DELIMITER || type == LLKeywordToken::TT_DOUBLE_QUOTATION_MARKS) { while( *cur && !cur_delimiter->isTail(cur)) { @@ -627,7 +794,7 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLW if( *cur ) { - cur += cur_delimiter->getLengthHead(); + cur += cur_delimiter->getLengthTail(); seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead() + cur_delimiter->getLengthTail(); } else @@ -648,12 +815,7 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLW seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead(); } - insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, style, editor); - /* - LLTextSegmentPtr text_segment = new LLNormalTextSegment( cur_delimiter->getColor(), seg_start, seg_end, editor ); - text_segment->setToken( cur_delimiter ); - insertSegment( seg_list, text_segment, text_len, defaultColor, editor); - */ + insertSegments(wtext, *seg_list, cur_delimiter, text_len, seg_start, seg_end, style, editor); // Note: we don't increment cur, since the end of one delimited seg may be immediately // followed by the start of another one. continue; @@ -662,34 +824,83 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLW // check against words llwchar prev = cur > base ? *(cur-1) : 0; - if( !iswalnum( prev ) && (prev != '_') ) + if (!iswalnum(prev) && prev != '_' && prev != '.') { - const llwchar* p = cur; - while( iswalnum( *p ) || (*p == '_') ) + const llwchar* word_start = cur; + S32 namespace_dots = 0; + const llwchar* last_dot = nullptr; + + // Find the full extent of the word, potentially including namespace dots + while (iswalnum(*cur) || *cur == '_' || (mLuauLanguage && *cur == '.' && iswalnum(*(cur+1)))) { - p++; + if (mLuauLanguage && *cur == '.') + { + namespace_dots++; + last_dot = cur; + } + cur++; } - S32 seg_len = (S32)(p - cur); - if( seg_len > 0 ) + + S32 seg_len = (S32)(cur - word_start); + if (seg_len > 0) { - WStringMapIndex word( cur, seg_len ); - word_token_map_t::iterator map_iter = mWordTokenMap.find(word); - if( map_iter != mWordTokenMap.end() ) + S32 seg_start = (S32)(word_start - base); + S32 seg_end = seg_start + seg_len; + + // First try to match the whole token (including dots for Lua namespaces) + word_token_map_t::iterator map_iter = mWordTokenMap.find(WStringMapIndex(word_start, seg_len)); + + if (map_iter != mWordTokenMap.end()) { + // Found a match for the complete token (including any namespace) LLKeywordToken* cur_token = map_iter->second; - S32 seg_start = (S32)(cur - base); - S32 seg_end = seg_start + seg_len; + insertSegments(wtext, *seg_list, cur_token, text_len, seg_start, seg_end, style, editor); + } + else if (namespace_dots > 0 && mLuauLanguage) + { + // If using Lua and we have namespace dots but didn't match the whole token, + // check if we have a match for just the namespace prefix (e.g., "ll") + if (last_dot > word_start) + { + // Get the namespace prefix (part before the first dot) + S32 prefix_len = (S32)(last_dot - word_start); + map_iter = mWordTokenMap.find(WStringMapIndex(word_start, prefix_len)); - // LL_INFOS("SyntaxLSL") << "Seg: [" << word.c_str() << "]" << LL_ENDL; + if (map_iter != mWordTokenMap.end()) + { + // Found a match for the namespace prefix, highlight just that part + LLKeywordToken* cur_token = map_iter->second; + insertSegments(wtext, *seg_list, cur_token, text_len, seg_start, seg_start + prefix_len, style, editor); - insertSegments(wtext, *seg_list,cur_token, text_len, seg_start, seg_end, style, editor); + // Now try to match the function part (after the dot) + const llwchar* func_part = last_dot + 1; + S32 func_len = (S32)(cur - func_part); + + if (func_len > 0) + { + // Look for complete function matches + map_iter = mWordTokenMap.find(WStringMapIndex(func_part, func_len)); + + if (map_iter != mWordTokenMap.end()) + { + // Found a match for the function part + LLKeywordToken* cur_token = map_iter->second; + insertSegments(wtext, *seg_list, cur_token, text_len, seg_start, seg_end, style, editor); + } + else + { + // No token found, continue without incrementing cur + // since we already advanced it while collecting the word + } + } + } + } } - cur += seg_len; - continue; + continue; // Continue to next token regardless of match } } - if( *cur && *cur != '\n' ) + if (*cur && *cur != '\n') { cur++; } @@ -798,6 +1009,14 @@ void LLKeywords::dump() LLKeywordToken* delimiter_token = *iter; delimiter_token->dump(); } + + LL_INFOS() << "LLKeywords::sRegexTokenList" << LL_ENDL; + for (token_list_t::iterator iter = mRegexTokenList.begin(); + iter != mRegexTokenList.end(); ++iter) + { + LLKeywordToken* regex_token = *iter; + regex_token->dump(); + } } void LLKeywordToken::dump() diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index 5892238593e..f5da50a0539 100644 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -36,6 +36,7 @@ #include #include #include +#include #include "llpointer.h" class LLTextSegment; @@ -53,6 +54,11 @@ class LLKeywordToken * - TT_ONE_SIDED_DELIMITER are for open-ended delimiters which are terminated by EOL. * - TT_TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with. * - TT_DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close. + * - TT_REGEX_MATCH are for pattern-based matching using regular expressions. + * For TT_REGEX_MATCH: mToken contains the start pattern, mDelimiter contains the end pattern (if any). + * If mDelimiter is empty, the entire match is considered one segment. + * If mDelimiter contains capture group references (e.g. \1, \2), these will be replaced with + * the corresponding capture groups from the start pattern match. */ typedef enum e_token_type { @@ -62,6 +68,7 @@ class LLKeywordToken TT_TWO_SIDED_DELIMITER, TT_ONE_SIDED_DELIMITER, TT_DOUBLE_QUOTATION_MARKS, + TT_REGEX_MATCH, // Following constants are more specific versions of the preceding ones TT_CONSTANT, // WORD TT_CONTROL, // WORD @@ -78,10 +85,20 @@ class LLKeywordToken mToken( token ), mColor( color ), mToolTip( tool_tip ), - mDelimiter( delimiter ) // right delimiter + mDelimiter( delimiter ), // right delimiter + mCompiledRegex( nullptr ) { } + ~LLKeywordToken() + { + if (mCompiledRegex) + { + delete mCompiledRegex; + mCompiledRegex = nullptr; + } + } + S32 getLengthHead() const { return static_cast(mToken.size()); } S32 getLengthTail() const { return static_cast(mDelimiter.size()); } bool isHead(const llwchar* s) const; @@ -91,6 +108,8 @@ class LLKeywordToken ETokenType getType() const { return mType; } const LLWString& getToolTip() const { return mToolTip; } const LLWString& getDelimiter() const { return mDelimiter; } + std::regex* getCompiledRegex() const { return mCompiledRegex; } + void setCompiledRegex(std::regex* regex) { mCompiledRegex = regex; } #ifdef _DEBUG void dump(); @@ -102,6 +121,7 @@ class LLKeywordToken LLUIColor mColor; LLWString mToolTip; LLWString mDelimiter; + std::regex* mCompiledRegex; }; class LLKeywords @@ -118,7 +138,7 @@ class LLKeywords const LLWString& text, class LLTextEditor& editor, LLStyleConstSP style); - void initialize(LLSD SyntaxXML); + void initialize(LLSD SyntaxXML, bool luau_language = false); void processTokens(); // Add the token as described @@ -189,10 +209,12 @@ class LLKeywords bool mLoaded; LLSD mSyntax; + bool mLuauLanguage; word_token_map_t mWordTokenMap; typedef std::deque token_list_t; token_list_t mLineTokenList; token_list_t mDelimiterTokenList; + token_list_t mRegexTokenList; typedef std::map> element_attributes_t; typedef element_attributes_t::const_iterator attribute_iterator_t; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index ff77b4d4820..7d0d0b72379 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1281,6 +1281,19 @@ LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, boo return NULL; } +LLScrollListItem* LLScrollListCtrl::getItemByValue(const std::string& value) +{ + for (LLScrollListItem* item : mItemList) + { + if (item->getValue().asString() == value) + { + return item; + } + } + + return NULL; +} + LLScrollListItem* LLScrollListCtrl::getItemByIndex(S32 index) { if (index >= 0 && index < (S32)mItemList.size()) diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 1f041003069..3028d1f02e2 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -262,7 +262,8 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler, bool selectItemByLabel(const std::string& item, bool case_sensitive = true, S32 column = 0); // false if item not found bool selectItemByPrefix(const std::string& target, bool case_sensitive = true, S32 column = -1); bool selectItemByPrefix(const LLWString& target, bool case_sensitive = true, S32 column = -1); - LLScrollListItem* getItemByLabel(const std::string& item, bool case_sensitive = true, S32 column = 0); + LLScrollListItem* getItemByLabel(const std::string& label, bool case_sensitive = true, S32 column = 0); + LLScrollListItem* getItemByValue(const std::string& value); LLScrollListItem* getItemByIndex(S32 index); std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 382847d68f8..1de12896ebe 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -185,6 +185,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mURLClickSignal(NULL), mIsFriendSignal(NULL), mIsObjectBlockedSignal(NULL), + mIsObjectReachableSignal(NULL), mMaxTextByteLength( p.max_text_length ), mFont(p.font), mFontShadow(p.font_shadow), @@ -290,6 +291,7 @@ LLTextBase::~LLTextBase() delete mURLClickSignal; delete mIsFriendSignal; delete mIsObjectBlockedSignal; + delete mIsObjectReachableSignal; } void LLTextBase::initFromParams(const LLTextBase::Params& p) @@ -1446,6 +1448,8 @@ void LLTextBase::reshape(S32 width, S32 height, bool called_from_parent) // up-to-date mVisibleTextRect updateRects(); + // Todo: This might be wrong. updateRects already sets needsReflow conditionaly. + // Reflow is expensive and doing it at any twith can be too much. needsReflow(); } } @@ -2235,6 +2239,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url)); registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url)); registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url)); + registrar.add("Url.ZoomInObject", boost::bind(&LLUrlAction::zoomInObject, url)); registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url)); registrar.add("Url.ShowParcelOnMap", boost::bind(&LLUrlAction::showParcelOnMap, url)); registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url)); @@ -2280,6 +2285,15 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) unblockButton->setVisible(is_blocked); } } + + if (mIsObjectReachableSignal) + { + bool is_reachable = *(*mIsObjectReachableSignal)(LLUUID(LLUrlAction::getObjectId(url))); + if (LLView* zoom_btn = menu->getChild("zoom_in")) + { + zoom_btn->setEnabled(is_reachable); + } + } menu->show(x, y); LLMenuGL::showPopup(this, menu, x, y); } @@ -3386,6 +3400,15 @@ boost::signals2::connection LLTextBase::setIsObjectBlockedCallback(const is_bloc return mIsObjectBlockedSignal->connect(cb); } +boost::signals2::connection LLTextBase::setIsObjectReachableCallback(const is_obj_reachable_signal_t::slot_type& cb) +{ + if (!mIsObjectReachableSignal) + { + mIsObjectReachableSignal = new is_obj_reachable_signal_t(); + } + return mIsObjectReachableSignal->connect(cb); +} + // // LLTextSegment // @@ -3764,7 +3787,7 @@ bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w { height = 0; width = 0; - if (num_chars > 0) + if (num_chars > 0 && (mStart + first_char >= 0)) { height = mFontHeight; const LLWString &text = getWText(); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 8ca653acb91..07cd9a1ee52 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -325,6 +325,7 @@ class LLTextBase typedef boost::signals2::signal is_friend_signal_t; typedef boost::signals2::signal is_blocked_signal_t; + typedef boost::signals2::signal is_obj_reachable_signal_t; struct LineSpacingParams : public LLInitParam::ChoiceBlock { @@ -535,6 +536,7 @@ class LLTextBase boost::signals2::connection setURLClickedCallback(const commit_signal_t::slot_type& cb); boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb); boost::signals2::connection setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb); + boost::signals2::connection setIsObjectReachableCallback(const is_obj_reachable_signal_t::slot_type& cb); void setWordWrap(bool wrap); LLScrollContainer* getScrollContainer() const { return mScroller; } @@ -783,6 +785,7 @@ class LLTextBase // Used to check if user with given ID is avatar's friend is_friend_signal_t* mIsFriendSignal; is_blocked_signal_t* mIsObjectBlockedSignal; + is_obj_reachable_signal_t* mIsObjectReachableSignal; LLUIString mLabel; // text label that is visible when no user text provided }; diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 5955a28fa32..56ab6e9bae1 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -1054,7 +1054,7 @@ bool LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, // if drop is set, it's time to call the callback to get the operation done if (handled && drop) { - handled = mHandleDropCallback(cargo_data, x, y, this); + handled = mHandleDropCallback(cargo_data, cargo_type, x, y, this); } // We accept only single tool drop on toolbars diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h index 5556406fbda..a3f044c256e 100644 --- a/indra/llui/lltoolbar.h +++ b/indra/llui/lltoolbar.h @@ -41,7 +41,7 @@ class LLIconCtrl; typedef boost::function tool_startdrag_callback_t; typedef boost::function tool_handledrag_callback_t; -typedef boost::function tool_handledrop_callback_t; +typedef boost::function tool_handledrop_callback_t; class LLToolBarButton : public LLButton { diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index e36dae39557..38d57205560 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -213,13 +213,8 @@ void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& rem void LLUI::setMousePositionScreen(S32 x, S32 y) { -#if defined(LL_DARWIN) - S32 screen_x = ll_round(((F32)x * getScaleFactor().mV[VX]) / LLView::getWindow()->getSystemUISize()); - S32 screen_y = ll_round(((F32)y * getScaleFactor().mV[VY]) / LLView::getWindow()->getSystemUISize()); -#else S32 screen_x = ll_round((F32)x * getScaleFactor().mV[VX]); S32 screen_y = ll_round((F32)y * getScaleFactor().mV[VY]); -#endif LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert()); } diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index fdae22cfa10..8b320b59cc3 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -117,6 +117,16 @@ void LLUrlAction::teleportToLocation(std::string url) } } +void LLUrlAction::zoomInObject(std::string url) +{ + LLUrlMatch match; + std::string object_id = getObjectId(url); + if (LLUUID::validate(object_id) && LLUrlRegistry::instance().findUrl(url, match)) + { + executeSLURL("secondlife:///app/object/" + object_id + "/zoomin/" + match.getLocation()); + } +} + void LLUrlAction::showLocationOnMap(std::string url) { LLUrlMatch match; diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index 8b7ab0e7c5e..56d459bb26f 100644 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -60,6 +60,10 @@ class LLUrlAction /// if the Url specifies an SL location, teleport there static void teleportToLocation(std::string url); + /// If the Url specifies an object id, attempt to zoom in. + /// If not possible to zoom in, show on map + static void zoomInObject(std::string url); + /// if the Url specifies an SL location, show it on a map static void showLocationOnMap(std::string url); diff --git a/indra/llwebrtc/CMakeLists.txt b/indra/llwebrtc/CMakeLists.txt index a18b7160034..eb10f4eee49 100644 --- a/indra/llwebrtc/CMakeLists.txt +++ b/indra/llwebrtc/CMakeLists.txt @@ -10,10 +10,6 @@ include(WebRTC) project(llwebrtc) -if (LINUX) - add_compile_options(-Wno-deprecated-declarations) # webrtc::CreateAudioDeviceWithDataObserver is deprecated -endif (LINUX) - set(llwebrtc_SOURCE_FILES llwebrtc.cpp ) @@ -46,7 +42,7 @@ if (WINDOWS) iphlpapi libcmt) # as the webrtc libraries are release, build this binary as release as well. - target_compile_options(llwebrtc PRIVATE "/MT") + target_compile_options(llwebrtc PRIVATE "/MT" "/Zc:wchar_t") if (USE_BUGSPLAT) set_target_properties(llwebrtc PROPERTIES PDB_OUTPUT_DIRECTORY "${SYMBOLS_STAGING_DIR}") endif (USE_BUGSPLAT) @@ -65,6 +61,8 @@ target_include_directories( llwebrtc INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) if (WINDOWS) set_property(TARGET llwebrtc PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreadedDebug") +else() + target_compile_options(llwebrtc PRIVATE -Wno-deprecated-declarations) # webrtc::CreateAudioDeviceWithDataObserver is deprecated endif (WINDOWS) ADD_CUSTOM_COMMAND(TARGET llwebrtc POST_BUILD diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 20951ff8167..2cf3f6bbf88 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -9,7 +9,7 @@ * 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. + * 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 @@ -32,41 +32,79 @@ #include "api/audio_codecs/audio_encoder_factory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_encoder_factory.h" +#include "api/audio/builtin_audio_processing_builder.h" #include "api/media_stream_interface.h" #include "api/media_stream_track.h" #include "modules/audio_processing/audio_buffer.h" #include "modules/audio_mixer/audio_mixer_impl.h" +#include "api/environment/environment_factory.h" namespace llwebrtc { +#if WEBRTC_WIN +static int16_t PLAYOUT_DEVICE_DEFAULT = webrtc::AudioDeviceModule::kDefaultDevice; +static int16_t RECORD_DEVICE_DEFAULT = webrtc::AudioDeviceModule::kDefaultDevice; +#else +static int16_t PLAYOUT_DEVICE_DEFAULT = 0; +static int16_t RECORD_DEVICE_DEFAULT = 0; +#endif -static int16_t PLAYOUT_DEVICE_DEFAULT = -1; -static int16_t PLAYOUT_DEVICE_BAD = -2; -static int16_t RECORD_DEVICE_DEFAULT = -1; -static int16_t RECORD_DEVICE_BAD = -2; -LLAudioDeviceObserver::LLAudioDeviceObserver() : mSumVector {0}, mMicrophoneEnergy(0.0) {} +// +// LLWebRTCAudioTransport implementation +// -float LLAudioDeviceObserver::getMicrophoneEnergy() { return mMicrophoneEnergy; } +LLWebRTCAudioTransport::LLWebRTCAudioTransport() : mMicrophoneEnergy(0.0) +{ + memset(mSumVector, 0, sizeof(mSumVector)); +} -// TODO: Pull smoothing/filtering code into a common helper function -// for LLAudioDeviceObserver and LLCustomProcessor +void LLWebRTCAudioTransport::SetEngineTransport(webrtc::AudioTransport* t) +{ + engine_.store(t, std::memory_order_release); +} -void LLAudioDeviceObserver::OnCaptureData(const void *audio_samples, - const size_t num_samples, - const size_t bytes_per_sample, - const size_t num_channels, - const uint32_t samples_per_sec) +int32_t LLWebRTCAudioTransport::RecordedDataIsAvailable(const void* audio_data, + size_t number_of_frames, + size_t bytes_per_frame, + size_t number_of_channels, + uint32_t samples_per_sec, + uint32_t total_delay_ms, + int32_t clock_drift, + uint32_t current_mic_level, + bool key_pressed, + uint32_t& new_mic_level) { + auto* engine = engine_.load(std::memory_order_acquire); + + // 1) Deliver to engine (authoritative). + int32_t ret = 0; + if (engine) + { + ret = engine->RecordedDataIsAvailable(audio_data, + number_of_frames, + bytes_per_frame, + number_of_channels, + samples_per_sec, + total_delay_ms, + clock_drift, + current_mic_level, + key_pressed, + new_mic_level); + } + + // 2) Calculate energy for microphone level monitoring // calculate the energy float energy = 0; - const short *samples = (const short *) audio_samples; - for (size_t index = 0; index < num_samples * num_channels; index++) + const short *samples = (const short *) audio_data; + + for (size_t index = 0; index < number_of_frames * number_of_channels; index++) { float sample = (static_cast(samples[index]) / (float) 32767); energy += sample * sample; } - + float gain = mGain.load(std::memory_order_relaxed); + energy = energy * gain * gain; // smooth it. size_t buffer_size = sizeof(mSumVector) / sizeof(mSumVector[0]); float totalSum = 0; @@ -78,18 +116,59 @@ void LLAudioDeviceObserver::OnCaptureData(const void *audio_samples, } mSumVector[i] = energy; totalSum += energy; - mMicrophoneEnergy = std::sqrt(totalSum / (num_samples * buffer_size)); + mMicrophoneEnergy = std::sqrt(totalSum / (number_of_frames * number_of_channels * buffer_size)); + + return ret; +} + +int32_t LLWebRTCAudioTransport::NeedMorePlayData(size_t number_of_frames, + size_t bytes_per_frame, + size_t number_of_channels, + uint32_t samples_per_sec, + void* audio_data, + size_t& number_of_samples_out, + int64_t* elapsed_time_ms, + int64_t* ntp_time_ms) +{ + auto* engine = engine_.load(std::memory_order_acquire); + if (!engine) + { + // No engine sink; output silence to be safe. + const size_t bytes = number_of_frames * bytes_per_frame * number_of_channels; + memset(audio_data, 0, bytes); + number_of_samples_out = bytes_per_frame; + return 0; + } + + // Only the engine should fill the buffer. + return engine->NeedMorePlayData(number_of_frames, + bytes_per_frame, + number_of_channels, + samples_per_sec, + audio_data, + number_of_samples_out, + elapsed_time_ms, + ntp_time_ms); } -void LLAudioDeviceObserver::OnRenderData(const void *audio_samples, - const size_t num_samples, - const size_t bytes_per_sample, - const size_t num_channels, - const uint32_t samples_per_sec) +void LLWebRTCAudioTransport::PullRenderData(int bits_per_sample, + int sample_rate, + size_t number_of_channels, + size_t number_of_frames, + void* audio_data, + int64_t* elapsed_time_ms, + int64_t* ntp_time_ms) { + auto* engine = engine_.load(std::memory_order_acquire); + + if (engine) + { + engine + ->PullRenderData(bits_per_sample, sample_rate, number_of_channels, number_of_frames, audio_data, elapsed_time_ms, ntp_time_ms); + } } -LLCustomProcessor::LLCustomProcessor() : mSampleRateHz(0), mNumChannels(0), mMicrophoneEnergy(0.0), mGain(1.0) +LLCustomProcessor::LLCustomProcessor(LLCustomProcessorStatePtr state) : mSampleRateHz(0), mNumChannels(0), mState(state) { memset(mSumVector, 0, sizeof(mSumVector)); } @@ -101,40 +180,61 @@ void LLCustomProcessor::Initialize(int sample_rate_hz, int num_channels) memset(mSumVector, 0, sizeof(mSumVector)); } -void LLCustomProcessor::Process(webrtc::AudioBuffer *audio_in) +void LLCustomProcessor::Process(webrtc::AudioBuffer *audio) { - webrtc::StreamConfig stream_config; - stream_config.set_sample_rate_hz(mSampleRateHz); - stream_config.set_num_channels(mNumChannels); - std::vector frame; - std::vector frame_samples; - - if (audio_in->num_channels() < 1 || audio_in->num_frames() < 480) + if (audio->num_channels() < 1 || audio->num_frames() < 480) { return; } - // grab the input audio - frame_samples.resize(stream_config.num_samples()); - frame.resize(stream_config.num_channels()); - for (size_t ch = 0; ch < stream_config.num_channels(); ++ch) + // calculate the energy + + float desired_gain = mState->getGain(); + if (mState->getDirty()) { - frame[ch] = &(frame_samples)[ch * stream_config.num_frames()]; + // We'll delay ramping by 30ms in order to clear out buffers that may + // have had content before muting. And for the last 20ms, we'll ramp + // down or up smoothly. + mRampFrames = 5; + + // we've changed our desired gain, so set the incremental + // gain change so that we smoothly step over 20ms + mGainStep = (desired_gain - mCurrentGain) / (mSampleRateHz / 50); } - audio_in->CopyTo(stream_config, &frame[0]); - - // calculate the energy - float energy = 0; - for (size_t index = 0; index < stream_config.num_samples(); index++) + if (mRampFrames) { - float sample = frame_samples[index]; - sample = sample * mGain; // apply gain - frame_samples[index] = sample; // write processed sample back to buffer. - energy += sample * sample; + if (mRampFrames-- > 2) + { + // don't change the gain if we're still in the 'don't move' phase + mGainStep = 0.0f; + } + } + else + { + // We've ramped all the way down, so don't step the gain any more and + // just maintaint he current gain. + mGainStep = 0.0f; + mCurrentGain = desired_gain; } - audio_in->CopyFrom(&frame[0], stream_config); + float energy = 0; + + auto chans = audio->channels(); + for (size_t ch = 0; ch < audio->num_channels(); ch++) + { + float* frame_samples = chans[ch]; + float gain = mCurrentGain; + for (size_t index = 0; index < audio->num_frames(); index++) + { + float sample = frame_samples[index]; + sample = sample * gain; // apply gain + frame_samples[index] = sample; // write processed sample back to buffer. + energy += sample * sample; + gain += mGainStep; + } + } + mCurrentGain += audio->num_frames() * mGainStep; // smooth it. size_t buffer_size = sizeof(mSumVector) / sizeof(mSumVector[0]); @@ -147,7 +247,7 @@ void LLCustomProcessor::Process(webrtc::AudioBuffer *audio_in) } mSumVector[i] = energy; totalSum += energy; - mMicrophoneEnergy = std::sqrt(totalSum / (stream_config.num_samples() * buffer_size)); + mState->setMicrophoneEnergy(std::sqrt(totalSum / (audio->num_channels() * audio->num_frames() * buffer_size))); } // @@ -159,89 +259,54 @@ LLWebRTCImpl::LLWebRTCImpl(LLWebRTCLogCallback* logCallback) : mPeerCustomProcessor(nullptr), mMute(true), mTuningMode(false), - mPlayoutDevice(0), - mRecordingDevice(0), - mTuningAudioDeviceObserver(nullptr) + mDevicesDeploying(0), + mGain(0.0f) { } void LLWebRTCImpl::init() { - mPlayoutDevice = 0; - mRecordingDevice = 0; - rtc::InitializeSSL(); + webrtc::InitializeSSL(); // Normal logging is rather spammy, so turn it off. - rtc::LogMessage::LogToDebug(rtc::LS_NONE); - rtc::LogMessage::SetLogToStderr(true); - rtc::LogMessage::AddLogToStream(mLogSink, rtc::LS_VERBOSE); + webrtc::LogMessage::LogToDebug(webrtc::LS_NONE); + webrtc::LogMessage::SetLogToStderr(true); + webrtc::LogMessage::AddLogToStream(mLogSink, webrtc::LS_VERBOSE); mTaskQueueFactory = webrtc::CreateDefaultTaskQueueFactory(); // Create the native threads. - mNetworkThread = rtc::Thread::CreateWithSocketServer(); + mNetworkThread = webrtc::Thread::CreateWithSocketServer(); mNetworkThread->SetName("WebRTCNetworkThread", nullptr); mNetworkThread->Start(); - mWorkerThread = rtc::Thread::Create(); + mWorkerThread = webrtc::Thread::Create(); mWorkerThread->SetName("WebRTCWorkerThread", nullptr); mWorkerThread->Start(); - mSignalingThread = rtc::Thread::Create(); + mSignalingThread = webrtc::Thread::Create(); mSignalingThread->SetName("WebRTCSignalingThread", nullptr); mSignalingThread->Start(); - mTuningAudioDeviceObserver = new LLAudioDeviceObserver; - mWorkerThread->PostTask( - [this]() - { - // Initialize the audio devices on the Worker Thread - mTuningDeviceModule = - webrtc::CreateAudioDeviceWithDataObserver(webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, - mTaskQueueFactory.get(), - std::unique_ptr(mTuningAudioDeviceObserver)); - - mTuningDeviceModule->Init(); - mTuningDeviceModule->SetPlayoutDevice(mPlayoutDevice); - mTuningDeviceModule->SetRecordingDevice(mRecordingDevice); - mTuningDeviceModule->EnableBuiltInAEC(false); - mTuningDeviceModule->SetAudioDeviceSink(this); - mTuningDeviceModule->InitMicrophone(); - mTuningDeviceModule->InitSpeaker(); - mTuningDeviceModule->SetStereoRecording(false); - mTuningDeviceModule->SetStereoPlayout(true); - mTuningDeviceModule->InitRecording(); - mTuningDeviceModule->InitPlayout(); - updateDevices(); - }); - mWorkerThread->BlockingCall( [this]() { - // the peer device module doesn't need an observer - // as we pull peer data after audio processing. - mPeerDeviceModule = webrtc::CreateAudioDeviceWithDataObserver(webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, - mTaskQueueFactory.get(), - nullptr); - mPeerDeviceModule->Init(); - mPeerDeviceModule->SetPlayoutDevice(mPlayoutDevice); - mPeerDeviceModule->SetRecordingDevice(mRecordingDevice); - mPeerDeviceModule->EnableBuiltInAEC(false); - mPeerDeviceModule->InitMicrophone(); - mPeerDeviceModule->InitSpeaker(); + webrtc::scoped_refptr realADM = + webrtc::AudioDeviceModule::Create(webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio, mTaskQueueFactory.get()); + mDeviceModule = webrtc::make_ref_counted(realADM); + mDeviceModule->SetObserver(this); }); // The custom processor allows us to retrieve audio data (and levels) // from after other audio processing such as AEC, AGC, etc. - mPeerCustomProcessor = new LLCustomProcessor; - webrtc::AudioProcessingBuilder apb; - apb.SetCapturePostProcessing(std::unique_ptr(mPeerCustomProcessor)); - mAudioProcessingModule = apb.Create(); + mPeerCustomProcessor = std::make_shared(); + webrtc::BuiltinAudioProcessingBuilder apb; + apb.SetCapturePostProcessing(std::make_unique(mPeerCustomProcessor)); + mAudioProcessingModule = apb.Build(webrtc::CreateEnvironment()); webrtc::AudioProcessing::Config apm_config; apm_config.echo_canceller.enabled = false; apm_config.echo_canceller.mobile_mode = false; apm_config.gain_controller1.enabled = false; - apm_config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog; - apm_config.gain_controller2.enabled = false; + apm_config.gain_controller2.enabled = true; apm_config.high_pass_filter.enabled = true; apm_config.noise_suppression.enabled = true; apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kVeryHigh; @@ -252,6 +317,7 @@ void LLWebRTCImpl::init() mAudioProcessingModule->ApplyConfig(apm_config); webrtc::ProcessingConfig processing_config; + processing_config.input_stream().set_num_channels(2); processing_config.input_stream().set_sample_rate_hz(48000); processing_config.output_stream().set_num_channels(2); @@ -266,18 +332,37 @@ void LLWebRTCImpl::init() mPeerConnectionFactory = webrtc::CreatePeerConnectionFactory(mNetworkThread.get(), mWorkerThread.get(), mSignalingThread.get(), - mPeerDeviceModule, + mDeviceModule, webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory(), nullptr /* video_encoder_factory */, nullptr /* video_decoder_factory */, nullptr /* audio_mixer */, mAudioProcessingModule); + mWorkerThread->PostTask( + [this]() + { + if (mDeviceModule) + { + mDeviceModule->EnableBuiltInAEC(false); + updateDevices(); + } + }); } void LLWebRTCImpl::terminate() { + mWorkerThread->BlockingCall( + [this]() + { + if (mDeviceModule) + { + mDeviceModule->ForceStopRecording(); + mDeviceModule->StopPlayout(); + } + }); + for (auto &connection : mPeerConnections) { connection->terminate(); @@ -289,69 +374,25 @@ void LLWebRTCImpl::terminate() mSignalingThread->BlockingCall([this]() { mPeerConnectionFactory = nullptr; }); - mPeerConnections.clear(); - mWorkerThread->BlockingCall( [this]() { - if (mTuningDeviceModule) + if (mDeviceModule) { - mTuningDeviceModule->StopRecording(); - mTuningDeviceModule->Terminate(); + mDeviceModule->Terminate(); } - if (mPeerDeviceModule) - { - mPeerDeviceModule->StopRecording(); - mPeerDeviceModule->Terminate(); - } - mTuningDeviceModule = nullptr; - mPeerDeviceModule = nullptr; - mTaskQueueFactory = nullptr; + mDeviceModule = nullptr; + mTaskQueueFactory = nullptr; }); - rtc::LogMessage::RemoveLogToStream(mLogSink); -} -// -// Devices functions -// -// Most device-related functionality needs to happen -// on the worker thread (the audio thread,) so those calls will be -// proxied over to that thread. -// -void LLWebRTCImpl::setRecording(bool recording) -{ - mWorkerThread->PostTask( - [this, recording]() - { - if (recording) - { - mPeerDeviceModule->SetStereoRecording(false); - mPeerDeviceModule->InitRecording(); - mPeerDeviceModule->StartRecording(); - } - else - { - mPeerDeviceModule->StopRecording(); - } - }); -} + // In case peer connections still somehow have jobs in workers, + // only clear connections up after clearing workers. + mNetworkThread = nullptr; + mWorkerThread = nullptr; + mSignalingThread = nullptr; -void LLWebRTCImpl::setPlayout(bool playing) -{ - mWorkerThread->PostTask( - [this, playing]() - { - if (playing) - { - mPeerDeviceModule->SetStereoPlayout(true); - mPeerDeviceModule->InitPlayout(); - mPeerDeviceModule->StartPlayout(); - } - else - { - mPeerDeviceModule->StopPlayout(); - } - }); + mPeerConnections.clear(); + webrtc::LogMessage::RemoveLogToStream(mLogSink); } void LLWebRTCImpl::setAudioConfig(LLWebRTCDeviceInterface::AudioConfig config) @@ -359,9 +400,9 @@ void LLWebRTCImpl::setAudioConfig(LLWebRTCDeviceInterface::AudioConfig config) webrtc::AudioProcessing::Config apm_config; apm_config.echo_canceller.enabled = config.mEchoCancellation; apm_config.echo_canceller.mobile_mode = false; - apm_config.gain_controller1.enabled = config.mAGC; - apm_config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog; - apm_config.gain_controller2.enabled = false; + apm_config.gain_controller1.enabled = false; + apm_config.gain_controller2.enabled = config.mAGC; + apm_config.gain_controller2.adaptive_digital.enabled = true; // auto-level speech apm_config.high_pass_filter.enabled = true; apm_config.transient_suppression.enabled = true; apm_config.pipeline.multi_channel_render = true; @@ -414,142 +455,142 @@ void LLWebRTCImpl::unsetDevicesObserver(LLWebRTCDevicesObserver *observer) } } -void ll_set_device_module_capture_device(rtc::scoped_refptr device_module, int16_t device) +// must be run in the worker thread. +void LLWebRTCImpl::workerDeployDevices() { -#if WEBRTC_WIN - if (device < 0) + if (!mDeviceModule) { - device_module->SetRecordingDevice(webrtc::AudioDeviceModule::kDefaultDevice); - } - else - { - device_module->SetRecordingDevice(device); + return; } -#else - // passed in default is -1, but the device list - // has it at 0 - device_module->SetRecordingDevice(device + 1); -#endif - device_module->InitMicrophone(); -} -void LLWebRTCImpl::setCaptureDevice(const std::string &id) -{ int16_t recordingDevice = RECORD_DEVICE_DEFAULT; - if (id != "Default") + int16_t recording_device_start = 0; + + if (mRecordingDevice != "Default") { - for (int16_t i = 0; i < mRecordingDeviceList.size(); i++) + for (int16_t i = recording_device_start; i < mRecordingDeviceList.size(); i++) { - if (mRecordingDeviceList[i].mID == id) + if (mRecordingDeviceList[i].mID == mRecordingDevice) { recordingDevice = i; +#if !WEBRTC_WIN + // linux and mac devices range from 1 to the end of the list, with the index 0 being the + // 'default' device. Windows has a special 'default' device and other devices are indexed + // from 0 + recordingDevice++; +#endif break; } } } - if (recordingDevice == mRecordingDevice) - { - return; - } - mRecordingDevice = recordingDevice; - if (mTuningMode) - { - mWorkerThread->PostTask([this, recordingDevice]() - { - ll_set_device_module_capture_device(mTuningDeviceModule, recordingDevice); - }); - } - else - { - mWorkerThread->PostTask([this, recordingDevice]() - { - bool recording = mPeerDeviceModule->Recording(); - if (recording) - { - mPeerDeviceModule->StopRecording(); - } - ll_set_device_module_capture_device(mPeerDeviceModule, recordingDevice); - if (recording) - { - mPeerDeviceModule->SetStereoRecording(false); - mPeerDeviceModule->InitRecording(); - mPeerDeviceModule->StartRecording(); - } - }); - } -} - -void ll_set_device_module_render_device(rtc::scoped_refptr device_module, int16_t device) -{ + mDeviceModule->StopPlayout(); + mDeviceModule->ForceStopRecording(); #if WEBRTC_WIN - if (device < 0) + if (recordingDevice < 0) { - device_module->SetPlayoutDevice(webrtc::AudioDeviceModule::kDefaultDevice); + mDeviceModule->SetRecordingDevice((webrtc::AudioDeviceModule::WindowsDeviceType)recordingDevice); } else { - device_module->SetPlayoutDevice(device); + mDeviceModule->SetRecordingDevice(recordingDevice); } #else - device_module->SetPlayoutDevice(device + 1); + mDeviceModule->SetRecordingDevice(recordingDevice); #endif - device_module->InitSpeaker(); -} + mDeviceModule->InitMicrophone(); + mDeviceModule->SetStereoRecording(false); + mDeviceModule->InitRecording(); -void LLWebRTCImpl::setRenderDevice(const std::string &id) -{ int16_t playoutDevice = PLAYOUT_DEVICE_DEFAULT; - if (id != "Default") + int16_t playout_device_start = 0; + if (mPlayoutDevice != "Default") { - for (int16_t i = 0; i < mPlayoutDeviceList.size(); i++) + for (int16_t i = playout_device_start; i < mPlayoutDeviceList.size(); i++) { - if (mPlayoutDeviceList[i].mID == id) + if (mPlayoutDeviceList[i].mID == mPlayoutDevice) { playoutDevice = i; +#if !WEBRTC_WIN + // linux and mac devices range from 1 to the end of the list, with the index 0 being the + // 'default' device. Windows has a special 'default' device and other devices are indexed + // from 0 + playoutDevice++; +#endif break; } } } - if (playoutDevice == mPlayoutDevice) + +#if WEBRTC_WIN + if (playoutDevice < 0) + { + mDeviceModule->SetPlayoutDevice((webrtc::AudioDeviceModule::WindowsDeviceType)playoutDevice); + } + else { - return; + mDeviceModule->SetPlayoutDevice(playoutDevice); } - mPlayoutDevice = playoutDevice; +#else + mDeviceModule->SetPlayoutDevice(playoutDevice); +#endif + mDeviceModule->InitSpeaker(); + mDeviceModule->SetStereoPlayout(true); + mDeviceModule->InitPlayout(); - if (mTuningMode) + if ((!mMute && mPeerConnections.size()) || mTuningMode) { - mWorkerThread->PostTask( - [this, playoutDevice]() - { - ll_set_device_module_render_device(mTuningDeviceModule, playoutDevice); - }); + mDeviceModule->ForceStartRecording(); } - else + + if (!mTuningMode) { - mWorkerThread->PostTask( - [this, playoutDevice]() + mDeviceModule->StartPlayout(); + } + mSignalingThread->PostTask( + [this] + { + for (auto& connection : mPeerConnections) { - bool playing = mPeerDeviceModule->Playing(); - if (playing) + if (mTuningMode) { - mPeerDeviceModule->StopPlayout(); + connection->enableSenderTracks(false); } - ll_set_device_module_render_device(mPeerDeviceModule, playoutDevice); - if (playing) + else { - mPeerDeviceModule->SetStereoPlayout(true); - mPeerDeviceModule->InitPlayout(); - mPeerDeviceModule->StartPlayout(); + connection->resetMute(); } - }); - } + connection->enableReceiverTracks(!mTuningMode); + } + if (1 < mDevicesDeploying.fetch_sub(1, std::memory_order_relaxed)) + { + mWorkerThread->PostTask([this] { workerDeployDevices(); }); + } + }); +} + +void LLWebRTCImpl::setCaptureDevice(const std::string &id) +{ + + mRecordingDevice = id; + deployDevices(); +} + +void LLWebRTCImpl::setRenderDevice(const std::string &id) +{ + mPlayoutDevice = id; + deployDevices(); } // updateDevices needs to happen on the worker thread. void LLWebRTCImpl::updateDevices() { - int16_t renderDeviceCount = mTuningDeviceModule->PlayoutDevices(); + if (!mDeviceModule) + { + return; + } + + int16_t renderDeviceCount = mDeviceModule->PlayoutDevices(); mPlayoutDeviceList.clear(); #if WEBRTC_WIN @@ -563,11 +604,11 @@ void LLWebRTCImpl::updateDevices() { char name[webrtc::kAdmMaxDeviceNameSize]; char guid[webrtc::kAdmMaxGuidSize]; - mTuningDeviceModule->PlayoutDeviceName(index, name, guid); + mDeviceModule->PlayoutDeviceName(index, name, guid); mPlayoutDeviceList.emplace_back(name, guid); } - int16_t captureDeviceCount = mTuningDeviceModule->RecordingDevices(); + int16_t captureDeviceCount = mDeviceModule->RecordingDevices(); mRecordingDeviceList.clear(); #if WEBRTC_WIN @@ -581,7 +622,7 @@ void LLWebRTCImpl::updateDevices() { char name[webrtc::kAdmMaxDeviceNameSize]; char guid[webrtc::kAdmMaxGuidSize]; - mTuningDeviceModule->RecordingDeviceName(index, name, guid); + mDeviceModule->RecordingDeviceName(index, name, guid); mRecordingDeviceList.emplace_back(name, guid); } @@ -593,10 +634,6 @@ void LLWebRTCImpl::updateDevices() void LLWebRTCImpl::OnDevicesUpdated() { - // reset these to a bad value so an update is forced - mRecordingDevice = RECORD_DEVICE_BAD; - mPlayoutDevice = PLAYOUT_DEVICE_BAD; - updateDevices(); } @@ -604,61 +641,117 @@ void LLWebRTCImpl::OnDevicesUpdated() void LLWebRTCImpl::setTuningMode(bool enable) { mTuningMode = enable; + if (!mTuningMode + && !mMute + && mPeerCustomProcessor + && mPeerCustomProcessor->getGain() != mGain) + { + mPeerCustomProcessor->setGain(mGain); + } mWorkerThread->PostTask( - [this, enable] { - if (enable) - { - mPeerDeviceModule->StopRecording(); - mPeerDeviceModule->StopPlayout(); - ll_set_device_module_render_device(mTuningDeviceModule, mPlayoutDevice); - ll_set_device_module_capture_device(mTuningDeviceModule, mRecordingDevice); - mTuningDeviceModule->InitPlayout(); - mTuningDeviceModule->InitRecording(); - mTuningDeviceModule->StartRecording(); - // TODO: Starting Playout on the TDM appears to create an audio artifact (click) - // in this case, so disabling it for now. We may have to do something different - // if we enable 'echo playback' via the TDM when tuning. - //mTuningDeviceModule->StartPlayout(); - } - else - { - mTuningDeviceModule->StopRecording(); - //mTuningDeviceModule->StopPlayout(); - ll_set_device_module_render_device(mPeerDeviceModule, mPlayoutDevice); - ll_set_device_module_capture_device(mPeerDeviceModule, mRecordingDevice); - mPeerDeviceModule->SetStereoPlayout(true); - mPeerDeviceModule->SetStereoRecording(false); - mPeerDeviceModule->InitPlayout(); - mPeerDeviceModule->InitRecording(); - mPeerDeviceModule->StartPlayout(); - mPeerDeviceModule->StartRecording(); - } - } - ); - mSignalingThread->PostTask( - [this, enable] + [this] { - for (auto &connection : mPeerConnections) - { - if (enable) - { - connection->enableSenderTracks(false); - } - else + mDeviceModule->SetTuning(mTuningMode, mMute); + mSignalingThread->PostTask( + [this] { - connection->resetMute(); - } - connection->enableReceiverTracks(!enable); - } + for (auto& connection : mPeerConnections) + { + if (mTuningMode) + { + connection->enableSenderTracks(false); + } + else + { + connection->resetMute(); + } + connection->enableReceiverTracks(!mTuningMode); + } + }); + }); +} + +void LLWebRTCImpl::deployDevices() +{ + if (0 < mDevicesDeploying.fetch_add(1, std::memory_order_relaxed)) + { + return; + } + mWorkerThread->PostTask( + [this] { + workerDeployDevices(); }); } -float LLWebRTCImpl::getTuningAudioLevel() { return -20 * log10f(mTuningAudioDeviceObserver->getMicrophoneEnergy()); } +float LLWebRTCImpl::getTuningAudioLevel() +{ + return mDeviceModule ? -20 * log10f(mDeviceModule->GetMicrophoneEnergy()) : std::numeric_limits::infinity(); +} + +void LLWebRTCImpl::setTuningMicGain(float gain) +{ + if (mTuningMode && mDeviceModule) + { + mDeviceModule->SetTuningMicGain(gain); + } +} -float LLWebRTCImpl::getPeerConnectionAudioLevel() { return -20 * log10f(mPeerCustomProcessor->getMicrophoneEnergy()); } +float LLWebRTCImpl::getPeerConnectionAudioLevel() +{ + return mTuningMode ? std::numeric_limits::infinity() + : (mPeerCustomProcessor ? -20 * log10f(mPeerCustomProcessor->getMicrophoneEnergy()) + : std::numeric_limits::infinity()); +} -void LLWebRTCImpl::setPeerConnectionGain(float gain) { mPeerCustomProcessor->setGain(gain); } +void LLWebRTCImpl::setMicGain(float gain) +{ + mGain = gain; + if (!mTuningMode && mPeerCustomProcessor) + { + mPeerCustomProcessor->setGain(gain); + } +} +void LLWebRTCImpl::setMute(bool mute, int delay_ms) +{ + if (mMute != mute) + { + mMute = mute; + intSetMute(mute, delay_ms); + } +} + +void LLWebRTCImpl::intSetMute(bool mute, int delay_ms) +{ + if (mPeerCustomProcessor) + { + mPeerCustomProcessor->setGain(mMute ? 0.0f : mGain); + } + if (mMute) + { + mWorkerThread->PostDelayedTask( + [this] + { + if (mDeviceModule) + { + mDeviceModule->ForceStopRecording(); + } + }, + webrtc::TimeDelta::Millis(delay_ms)); + } + else + { + mWorkerThread->PostTask( + [this] + { + if (mDeviceModule) + { + mDeviceModule->InitRecording(); + mDeviceModule->ForceStartRecording(); + } + }); + } +} // // Peer Connection Helpers @@ -666,34 +759,32 @@ void LLWebRTCImpl::setPeerConnectionGain(float gain) { mPeerCustomProcessor->set LLWebRTCPeerConnectionInterface *LLWebRTCImpl::newPeerConnection() { - rtc::scoped_refptr peerConnection = rtc::scoped_refptr(new rtc::RefCountedObject()); + bool empty = mPeerConnections.empty(); + webrtc::scoped_refptr peerConnection = webrtc::scoped_refptr(new webrtc::RefCountedObject()); peerConnection->init(this); - - mPeerConnections.emplace_back(peerConnection); - // Should it really start disabled? - // Seems like something doesn't get the memo and senders need to be reset later - // to remove the voice indicator from taskbar - peerConnection->enableSenderTracks(false); if (mPeerConnections.empty()) { - setRecording(true); - setPlayout(true); + intSetMute(mMute); } + mPeerConnections.emplace_back(peerConnection); + + peerConnection->enableSenderTracks(false); + peerConnection->resetMute(); return peerConnection.get(); } void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_connection) { - std::vector>::iterator it = + std::vector>::iterator it = std::find(mPeerConnections.begin(), mPeerConnections.end(), peer_connection); if (it != mPeerConnections.end()) { + // Todo: make sure conection had no jobs in workers mPeerConnections.erase(it); - } - if (mPeerConnections.empty()) - { - setRecording(false); - setPlayout(false); + if (mPeerConnections.empty()) + { + intSetMute(true); + } } } @@ -708,7 +799,8 @@ LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() : mWebRTCImpl(nullptr), mPeerConnection(nullptr), mMute(MUTE_INITIAL), - mAnswerReceived(false) + mAnswerReceived(false), + mPendingJobs(0) { } @@ -716,6 +808,10 @@ LLWebRTCPeerConnectionImpl::~LLWebRTCPeerConnectionImpl() { mSignalingObserverList.clear(); mDataObserverList.clear(); + if (mPendingJobs > 0) + { + RTC_LOG(LS_ERROR) << __FUNCTION__ << "Destroying a connection that has " << std::to_string(mPendingJobs) << " unfinished jobs that might cause workers to crash"; + } } // @@ -727,9 +823,11 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl) mWebRTCImpl = webrtc_impl; mPeerConnectionFactory = mWebRTCImpl->getPeerConnectionFactory(); } + void LLWebRTCPeerConnectionImpl::terminate() { - mWebRTCImpl->SignalingBlockingCall( + mPendingJobs++; + mWebRTCImpl->PostSignalingTask( [this]() { if (mPeerConnection) @@ -753,7 +851,6 @@ void LLWebRTCPeerConnectionImpl::terminate() track->set_enabled(false); } } - mPeerConnection->SetAudioRecording(false); mPeerConnection->Close(); if (mLocalStream) @@ -772,7 +869,9 @@ void LLWebRTCPeerConnectionImpl::terminate() observer->OnPeerConnectionClosed(); } } + mPendingJobs--; }); + mPeerConnectionFactory.release(); } void LLWebRTCPeerConnectionImpl::setSignalingObserver(LLWebRTCSignalingObserver *observer) { mSignalingObserverList.emplace_back(observer); } @@ -793,6 +892,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti RTC_DCHECK(!mPeerConnection); mAnswerReceived = false; + mPendingJobs++; mWebRTCImpl->PostSignalingTask( [this,options]() { @@ -826,6 +926,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti { observer->OnRenegotiationNeeded(); } + mPendingJobs--; return; } @@ -840,7 +941,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti mDataChannel->RegisterObserver(this); } - cricket::AudioOptions audioOptions; + webrtc::AudioOptions audioOptions; audioOptions.auto_gain_control = true; audioOptions.echo_cancellation = true; audioOptions.noise_suppression = true; @@ -848,7 +949,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti mLocalStream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream"); - rtc::scoped_refptr audio_track( + webrtc::scoped_refptr audio_track( mPeerConnectionFactory->CreateAudioTrack("SLAudio", mPeerConnectionFactory->CreateAudioSource(audioOptions).get())); audio_track->set_enabled(false); mLocalStream->AddTrack(audio_track); @@ -862,7 +963,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti webrtc::RtpParameters params; webrtc::RtpCodecParameters codecparam; codecparam.name = "opus"; - codecparam.kind = cricket::MEDIA_TYPE_AUDIO; + codecparam.kind = webrtc::MediaType::AUDIO; codecparam.clock_rate = 48000; codecparam.num_channels = 2; codecparam.parameters["stereo"] = "1"; @@ -877,7 +978,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti webrtc::RtpParameters params; webrtc::RtpCodecParameters codecparam; codecparam.name = "opus"; - codecparam.kind = cricket::MEDIA_TYPE_AUDIO; + codecparam.kind = webrtc::MediaType::AUDIO; codecparam.clock_rate = 48000; codecparam.num_channels = 2; codecparam.parameters["stereo"] = "1"; @@ -888,6 +989,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti webrtc::PeerConnectionInterface::RTCOfferAnswerOptions offerOptions; mPeerConnection->CreateOffer(this, offerOptions); + mPendingJobs--; }); return true; @@ -904,7 +1006,6 @@ void LLWebRTCPeerConnectionImpl::enableSenderTracks(bool enable) // set_enabled shouldn't be done on the worker thread. if (mPeerConnection) { - mPeerConnection->SetAudioRecording(enable); auto senders = mPeerConnection->GetSenders(); for (auto &sender : senders) { @@ -931,6 +1032,7 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp) { RTC_LOG(LS_INFO) << __FUNCTION__ << " Remote SDP: " << sdp; + mPendingJobs++; mWebRTCImpl->PostSignalingTask( [this, sdp]() { @@ -938,8 +1040,9 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp) { RTC_LOG(LS_INFO) << __FUNCTION__ << " " << mPeerConnection->peer_connection_state(); mPeerConnection->SetRemoteDescription(webrtc::CreateSessionDescription(webrtc::SdpType::kAnswer, sdp), - rtc::scoped_refptr(this)); + webrtc::scoped_refptr(this)); } + mPendingJobs--; }); } @@ -951,22 +1054,23 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp) void LLWebRTCPeerConnectionImpl::setMute(bool mute) { EMicMuteState new_state = mute ? MUTE_MUTED : MUTE_UNMUTED; - if (new_state == mMute) - { - return; // no change - } + + // even if mute hasn't changed, we still need to update the mute + // state on the connections to handle cases where the 'Default' device + // has changed in the OS (unplugged headset, etc.) which messes + // with the mute state. + bool force_reset = mMute == MUTE_INITIAL && mute; bool enable = !mute; mMute = new_state; + + mPendingJobs++; mWebRTCImpl->PostSignalingTask( [this, force_reset, enable]() { if (mPeerConnection) { - // SetAudioRecording must be called before enabling/disabling tracks. - mPeerConnection->SetAudioRecording(enable); - auto senders = mPeerConnection->GetSenders(); RTC_LOG(LS_INFO) << __FUNCTION__ << (mMute ? "disabling" : "enabling") << " streams count " << senders.size(); @@ -985,6 +1089,7 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute) track->set_enabled(enable); } } + mPendingJobs--; } }); } @@ -1006,6 +1111,7 @@ void LLWebRTCPeerConnectionImpl::resetMute() void LLWebRTCPeerConnectionImpl::setReceiveVolume(float volume) { + mPendingJobs++; mWebRTCImpl->PostSignalingTask( [this, volume]() { @@ -1024,11 +1130,13 @@ void LLWebRTCPeerConnectionImpl::setReceiveVolume(float volume) } } } + mPendingJobs--; }); } void LLWebRTCPeerConnectionImpl::setSendVolume(float volume) { + mPendingJobs++; mWebRTCImpl->PostSignalingTask( [this, volume]() { @@ -1039,6 +1147,7 @@ void LLWebRTCPeerConnectionImpl::setSendVolume(float volume) track->GetSource()->SetVolume(volume*5.0); } } + mPendingJobs--; }); } @@ -1046,14 +1155,14 @@ void LLWebRTCPeerConnectionImpl::setSendVolume(float volume) // PeerConnectionObserver implementation. // -void LLWebRTCPeerConnectionImpl::OnAddTrack(rtc::scoped_refptr receiver, - const std::vector> &streams) +void LLWebRTCPeerConnectionImpl::OnAddTrack(webrtc::scoped_refptr receiver, + const std::vector> &streams) { RTC_LOG(LS_INFO) << __FUNCTION__ << " " << receiver->id(); webrtc::RtpParameters params; webrtc::RtpCodecParameters codecparam; codecparam.name = "opus"; - codecparam.kind = cricket::MEDIA_TYPE_AUDIO; + codecparam.kind = webrtc::MediaType::AUDIO; codecparam.clock_rate = 48000; codecparam.num_channels = 2; codecparam.parameters["stereo"] = "1"; @@ -1062,12 +1171,12 @@ void LLWebRTCPeerConnectionImpl::OnAddTrack(rtc::scoped_refptrSetParameters(params); } -void LLWebRTCPeerConnectionImpl::OnRemoveTrack(rtc::scoped_refptr receiver) +void LLWebRTCPeerConnectionImpl::OnRemoveTrack(webrtc::scoped_refptr receiver) { RTC_LOG(LS_INFO) << __FUNCTION__ << " " << receiver->id(); } -void LLWebRTCPeerConnectionImpl::OnDataChannel(rtc::scoped_refptr channel) +void LLWebRTCPeerConnectionImpl::OnDataChannel(webrtc::scoped_refptr channel) { if (mDataChannel) { @@ -1115,11 +1224,13 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf { case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected: { + mPendingJobs++; mWebRTCImpl->PostWorkerTask([this]() { for (auto &observer : mSignalingObserverList) { observer->OnAudioEstablished(this); } + mPendingJobs--; }); break; } @@ -1154,23 +1265,23 @@ static std::string iceCandidateToTrickleString(const webrtc::IceCandidateInterfa candidate->candidate().address().ipaddr().ToString() << " " << candidate->candidate().address().PortAsString() << " typ "; - if (candidate->candidate().type() == cricket::LOCAL_PORT_TYPE) + if (candidate->candidate().type() == webrtc::IceCandidateType::kHost) { candidate_stream << "host"; } - else if (candidate->candidate().type() == cricket::STUN_PORT_TYPE) + else if (candidate->candidate().type() == webrtc::IceCandidateType::kSrflx) { candidate_stream << "srflx " << "raddr " << candidate->candidate().related_address().ipaddr().ToString() << " " << "rport " << candidate->candidate().related_address().PortAsString(); } - else if (candidate->candidate().type() == cricket::RELAY_PORT_TYPE) + else if (candidate->candidate().type() == webrtc::IceCandidateType::kRelay) { candidate_stream << "relay " << "raddr " << candidate->candidate().related_address().ipaddr().ToString() << " " << "rport " << candidate->candidate().related_address().PortAsString(); } - else if (candidate->candidate().type() == cricket::PRFLX_PORT_TYPE) + else if (candidate->candidate().type() == webrtc::IceCandidateType::kPrflx) { candidate_stream << "prflx " << "raddr " << candidate->candidate().related_address().ipaddr().ToString() << " " << @@ -1265,7 +1376,7 @@ void LLWebRTCPeerConnectionImpl::OnSuccess(webrtc::SessionDescriptionInterface * mPeerConnection->SetLocalDescription(std::unique_ptr( webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, mangled_sdp)), - rtc::scoped_refptr(this)); + webrtc::scoped_refptr(this)); } @@ -1375,13 +1486,15 @@ void LLWebRTCPeerConnectionImpl::sendData(const std::string& data, bool binary) { if (mDataChannel) { - rtc::CopyOnWriteBuffer cowBuffer(data.data(), data.length()); + webrtc::CopyOnWriteBuffer cowBuffer(data.data(), data.length()); webrtc::DataBuffer buffer(cowBuffer, binary); + mPendingJobs++; mWebRTCImpl->PostNetworkTask([this, buffer]() { if (mDataChannel) { mDataChannel->Send(buffer); } + mPendingJobs--; }); } } @@ -1429,6 +1542,7 @@ void terminate() if (gWebRTCImpl) { gWebRTCImpl->terminate(); + delete gWebRTCImpl; gWebRTCImpl = nullptr; } } diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h index c6fdb909ddc..7d06b7d2b40 100644 --- a/indra/llwebrtc/llwebrtc.h +++ b/indra/llwebrtc/llwebrtc.h @@ -159,7 +159,10 @@ class LLWebRTCDeviceInterface virtual void setTuningMode(bool enable) = 0; virtual float getTuningAudioLevel() = 0; // for use during tuning virtual float getPeerConnectionAudioLevel() = 0; // for use when not tuning - virtual void setPeerConnectionGain(float gain) = 0; + virtual void setMicGain(float gain) = 0; + virtual void setTuningMicGain(float gain) = 0; + + virtual void setMute(bool mute, int delay_ms = 0) = 0; }; // LLWebRTCAudioInterface provides the viewer with a way diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index b6294dbd4a5..01cfb17ced2 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -54,12 +54,12 @@ #include "rtc_base/ref_counted_object.h" #include "rtc_base/ssl_adapter.h" #include "rtc_base/thread.h" +#include "rtc_base/logging.h" #include "api/peer_connection_interface.h" #include "api/media_stream_interface.h" #include "api/create_peerconnection_factory.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_device/include/audio_device_data_observer.h" -#include "rtc_base/task_queue.h" #include "api/task_queue/task_queue_factory.h" #include "api/task_queue/default_task_queue_factory.h" #include "modules/audio_device/include/audio_device_defines.h" @@ -69,35 +69,30 @@ namespace llwebrtc class LLWebRTCPeerConnectionImpl; -class LLWebRTCLogSink : public rtc::LogSink { +class LLWebRTCLogSink : public webrtc::LogSink +{ public: - LLWebRTCLogSink(LLWebRTCLogCallback* callback) : - mCallback(callback) - { - } + LLWebRTCLogSink(LLWebRTCLogCallback* callback) : mCallback(callback) {} // Destructor: close the log file - ~LLWebRTCLogSink() override - { - } + ~LLWebRTCLogSink() override { mCallback = nullptr; } - void OnLogMessage(const std::string& msg, - rtc::LoggingSeverity severity) override + void OnLogMessage(const std::string& msg, webrtc::LoggingSeverity severity) override { if (mCallback) { - switch(severity) + switch (severity) { - case rtc::LS_VERBOSE: + case webrtc::LS_VERBOSE: mCallback->LogMessage(LLWebRTCLogCallback::LOG_LEVEL_VERBOSE, msg); break; - case rtc::LS_INFO: + case webrtc::LS_INFO: mCallback->LogMessage(LLWebRTCLogCallback::LOG_LEVEL_VERBOSE, msg); break; - case rtc::LS_WARNING: + case webrtc::LS_WARNING: mCallback->LogMessage(LLWebRTCLogCallback::LOG_LEVEL_VERBOSE, msg); break; - case rtc::LS_ERROR: + case webrtc::LS_ERROR: mCallback->LogMessage(LLWebRTCLogCallback::LOG_LEVEL_VERBOSE, msg); break; default: @@ -118,79 +113,318 @@ class LLWebRTCLogSink : public rtc::LogSink { LLWebRTCLogCallback* mCallback; }; -// Implements a class allowing capture of audio data -// to determine audio level of the microphone. -class LLAudioDeviceObserver : public webrtc::AudioDeviceDataObserver +// ----------------------------------------------------------------------------- +// A proxy transport that forwards capture data to two AudioTransport sinks: +// - the "engine" (libwebrtc's VoiceEngine) +// - the "user" (your app's listener) +// +// Playout (NeedMorePlayData) goes only to the engine by default to avoid +// double-writing into the output buffer. See notes below if you want a tap. +// ----------------------------------------------------------------------------- +class LLWebRTCAudioTransport : public webrtc::AudioTransport { - public: - LLAudioDeviceObserver(); - - // Retrieve the RMS audio loudness - float getMicrophoneEnergy(); - - // Data retrieved from the caputure device is - // passed in here for processing. - void OnCaptureData(const void *audio_samples, - const size_t num_samples, - const size_t bytes_per_sample, - const size_t num_channels, - const uint32_t samples_per_sec) override; - - // This is for data destined for the render device. - // not currently used. - void OnRenderData(const void *audio_samples, - const size_t num_samples, - const size_t bytes_per_sample, - const size_t num_channels, - const uint32_t samples_per_sec) override; +public: + LLWebRTCAudioTransport(); + + void SetEngineTransport(webrtc::AudioTransport* t); + + // -------- Capture path: fan out to both sinks -------- + int32_t RecordedDataIsAvailable(const void* audio_data, + size_t number_of_samples, + size_t bytes_per_sample, + size_t number_of_channels, + uint32_t samples_per_sec, + uint32_t total_delay_ms, + int32_t clock_drift, + uint32_t current_mic_level, + bool key_pressed, + uint32_t& new_mic_level) override; + + // -------- Playout path: delegate to engine only -------- + int32_t NeedMorePlayData(size_t number_of_samples, + size_t bytes_per_sample, + size_t number_of_channels, + uint32_t samples_per_sec, + void* audio_data, + size_t& number_of_samples_out, + int64_t* elapsed_time_ms, + int64_t* ntp_time_ms) override; + + // Method to pull mixed render audio data from all active VoE channels. + // The data will not be passed as reference for audio processing internally. + void PullRenderData(int bits_per_sample, + int sample_rate, + size_t number_of_channels, + size_t number_of_frames, + void* audio_data, + int64_t* elapsed_time_ms, + int64_t* ntp_time_ms) override; + + float GetMicrophoneEnergy() { return mMicrophoneEnergy.load(std::memory_order_relaxed); } + void SetGain(float gain) { mGain.store(gain, std::memory_order_relaxed); } + +private: + std::atomic engine_{ nullptr }; + static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing (30 frames) + float mSumVector[NUM_PACKETS_TO_FILTER]; + std::atomic mMicrophoneEnergy; + std::atomic mGain{ 0.0f }; - protected: - static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing (30 frames) - float mSumVector[NUM_PACKETS_TO_FILTER]; - float mMicrophoneEnergy; }; + +// ----------------------------------------------------------------------------- +// LLWebRTCAudioDeviceModule +// - Wraps a real ADM to provide microphone energy for tuning +// ----------------------------------------------------------------------------- +class LLWebRTCAudioDeviceModule : public webrtc::AudioDeviceModule +{ +public: + explicit LLWebRTCAudioDeviceModule(webrtc::scoped_refptr inner) : inner_(std::move(inner)), tuning_(false) + { + RTC_CHECK(inner_); + } + + // ----- AudioDeviceModule interface: we mostly forward to |inner_| ----- + int32_t ActiveAudioLayer(AudioLayer* audioLayer) const override { return inner_->ActiveAudioLayer(audioLayer); } + + int32_t RegisterAudioCallback(webrtc::AudioTransport* engine_transport) override + { + // The engine registers its transport here. We put our audio transport between engine and ADM. + audio_transport_.SetEngineTransport(engine_transport); + // Register our proxy with the real ADM. + return inner_->RegisterAudioCallback(&audio_transport_); + } + + int32_t Init() override { return inner_->Init(); } + int32_t Terminate() override { return inner_->Terminate(); } + bool Initialized() const override { return inner_->Initialized(); } + + // --- Device enumeration/selection (forward) --- + int16_t PlayoutDevices() override { return inner_->PlayoutDevices(); } + int16_t RecordingDevices() override { return inner_->RecordingDevices(); } + int32_t PlayoutDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], char guid[webrtc::kAdmMaxGuidSize]) override + { + return inner_->PlayoutDeviceName(index, name, guid); + } + int32_t RecordingDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], char guid[webrtc::kAdmMaxGuidSize]) override + { + return inner_->RecordingDeviceName(index, name, guid); + } + int32_t SetPlayoutDevice(uint16_t index) override { return inner_->SetPlayoutDevice(index); } + int32_t SetRecordingDevice(uint16_t index) override { return inner_->SetRecordingDevice(index); } + + // Windows default/communications selectors, if your branch exposes them: + int32_t SetPlayoutDevice(WindowsDeviceType type) override { return inner_->SetPlayoutDevice(type); } + int32_t SetRecordingDevice(WindowsDeviceType type) override { return inner_->SetRecordingDevice(type); } + + // --- Init/start/stop (forward) --- + int32_t InitPlayout() override { return inner_->InitPlayout(); } + bool PlayoutIsInitialized() const override { return inner_->PlayoutIsInitialized(); } + int32_t StartPlayout() override { + if (tuning_) return 0; // For tuning, don't allow playout + return inner_->StartPlayout(); + } + int32_t StopPlayout() override { return inner_->StopPlayout(); } + bool Playing() const override { return inner_->Playing(); } + + int32_t InitRecording() override { return inner_->InitRecording(); } + bool RecordingIsInitialized() const override { return inner_->RecordingIsInitialized(); } + int32_t StartRecording() override { + // ignore start recording as webrtc.lib will + // send one when streams first connect, resulting + // in an inadvertant 'recording' when mute is on. + // We take full control of StartRecording via + // ForceStartRecording below. + return 0; + } + int32_t StopRecording() override { + // ignore stop recording as webrtc.lib will send one when streams shut down, + // even if there are other streams in place. Start/Stop recording are entirely + // controlled by the app + return 0; + } + int32_t ForceStartRecording() { return inner_->StartRecording(); } + int32_t ForceStopRecording() { return inner_->StopRecording(); } + bool Recording() const override { return inner_->Recording(); } + + // --- Stereo opts (forward if available on your branch) --- + int32_t SetStereoPlayout(bool enable) override { return inner_->SetStereoPlayout(enable); } + int32_t SetStereoRecording(bool enable) override { return inner_->SetStereoRecording(enable); } + int32_t PlayoutIsAvailable(bool* available) override { return inner_->PlayoutIsAvailable(available); } + int32_t RecordingIsAvailable(bool* available) override { return inner_->RecordingIsAvailable(available); } + + // --- AGC/Volume/Mute/etc. (forward) --- + int32_t SetMicrophoneVolume(uint32_t volume) override { return inner_->SetMicrophoneVolume(volume); } + int32_t MicrophoneVolume(uint32_t* volume) const override { return inner_->MicrophoneVolume(volume); } + + // --- Speaker/Microphone init (forward) --- + int32_t InitSpeaker() override { return inner_->InitSpeaker(); } + bool SpeakerIsInitialized() const override { return inner_->SpeakerIsInitialized(); } + int32_t InitMicrophone() override { return inner_->InitMicrophone(); } + bool MicrophoneIsInitialized() const override { return inner_->MicrophoneIsInitialized(); } + + // --- Speaker Volume (forward) --- + int32_t SpeakerVolumeIsAvailable(bool* available) override { return inner_->SpeakerVolumeIsAvailable(available); } + int32_t SetSpeakerVolume(uint32_t volume) override { return inner_->SetSpeakerVolume(volume); } + int32_t SpeakerVolume(uint32_t* volume) const override { return inner_->SpeakerVolume(volume); } + int32_t MaxSpeakerVolume(uint32_t* maxVolume) const override { return inner_->MaxSpeakerVolume(maxVolume); } + int32_t MinSpeakerVolume(uint32_t* minVolume) const override { return inner_->MinSpeakerVolume(minVolume); } + + // --- Microphone Volume (forward) --- + int32_t MicrophoneVolumeIsAvailable(bool* available) override { return inner_->MicrophoneVolumeIsAvailable(available); } + int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override { return inner_->MaxMicrophoneVolume(maxVolume); } + int32_t MinMicrophoneVolume(uint32_t* minVolume) const override { return inner_->MinMicrophoneVolume(minVolume); } + + // --- Speaker Mute (forward) --- + int32_t SpeakerMuteIsAvailable(bool* available) override { return inner_->SpeakerMuteIsAvailable(available); } + int32_t SetSpeakerMute(bool enable) override { return inner_->SetSpeakerMute(enable); } + int32_t SpeakerMute(bool* enabled) const override { return inner_->SpeakerMute(enabled); } + + // --- Microphone Mute (forward) --- + int32_t MicrophoneMuteIsAvailable(bool* available) override { return inner_->MicrophoneMuteIsAvailable(available); } + int32_t SetMicrophoneMute(bool enable) override { return inner_->SetMicrophoneMute(enable); } + int32_t MicrophoneMute(bool* enabled) const override { return inner_->MicrophoneMute(enabled); } + + // --- Stereo Support (forward) --- + int32_t StereoPlayoutIsAvailable(bool* available) const override { return inner_->StereoPlayoutIsAvailable(available); } + int32_t StereoPlayout(bool* enabled) const override { return inner_->StereoPlayout(enabled); } + int32_t StereoRecordingIsAvailable(bool* available) const override { return inner_->StereoRecordingIsAvailable(available); } + int32_t StereoRecording(bool* enabled) const override { return inner_->StereoRecording(enabled); } + + // --- Delay/Timing (forward) --- + int32_t PlayoutDelay(uint16_t* delayMS) const override { return inner_->PlayoutDelay(delayMS); } + + // --- Built-in Audio Processing (forward) --- + bool BuiltInAECIsAvailable() const override { return inner_->BuiltInAECIsAvailable(); } + bool BuiltInAGCIsAvailable() const override { return inner_->BuiltInAGCIsAvailable(); } + bool BuiltInNSIsAvailable() const override { return inner_->BuiltInNSIsAvailable(); } + int32_t EnableBuiltInAEC(bool enable) override { return inner_->EnableBuiltInAEC(enable); } + int32_t EnableBuiltInAGC(bool enable) override { return inner_->EnableBuiltInAGC(enable); } + int32_t EnableBuiltInNS(bool enable) override { return inner_->EnableBuiltInNS(enable); } + + // --- Additional AudioDeviceModule methods (forward) --- + int32_t GetPlayoutUnderrunCount() const override { return inner_->GetPlayoutUnderrunCount(); } + + // Used to generate RTC stats. If not implemented, RTCAudioPlayoutStats will + // not be present in the stats. + std::optional GetStats() const override { return inner_->GetStats(); } + +// Only supported on iOS. +#if defined(WEBRTC_IOS) + virtual int GetPlayoutAudioParameters(AudioParameters* params) const override { return inner_->GetPlayoutAudioParameters(params); } + virtual int GetRecordAudioParameters(AudioParameters* params) override { return inner_->GetRecordAudioParameters(params); } +#endif // WEBRTC_IOS + + virtual int32_t GetPlayoutDevice() const override { return inner_->GetPlayoutDevice(); } + virtual int32_t GetRecordingDevice() const override { return inner_->GetRecordingDevice(); } + virtual int32_t SetObserver(webrtc::AudioDeviceObserver* observer) override { return inner_->SetObserver(observer); } + + // tuning microphone energy calculations + float GetMicrophoneEnergy() { return audio_transport_.GetMicrophoneEnergy(); } + void SetTuningMicGain(float gain) { audio_transport_.SetGain(gain); } + void SetTuning(bool tuning, bool mute) + { + tuning_ = tuning; + if (tuning) + { + inner_->InitRecording(); + inner_->StartRecording(); + inner_->StopPlayout(); + } + else + { + if (mute) + { + inner_->StopRecording(); + } + else + { + inner_->InitRecording(); + inner_->StartRecording(); + } + inner_->StartPlayout(); + } + } + +protected: + ~LLWebRTCAudioDeviceModule() override = default; + +private: + webrtc::scoped_refptr inner_; + LLWebRTCAudioTransport audio_transport_; + + bool tuning_; +}; + +class LLCustomProcessorState +{ + +public: + float getMicrophoneEnergy() { return mMicrophoneEnergy.load(std::memory_order_relaxed); } + void setMicrophoneEnergy(float energy) { mMicrophoneEnergy.store(energy, std::memory_order_relaxed); } + + void setGain(float gain) + { + mGain.store(gain, std::memory_order_relaxed); + mDirty.store(true, std::memory_order_relaxed); + } + + float getGain() { return mGain.load(std::memory_order_relaxed); } + + bool getDirty() { return mDirty.exchange(false, std::memory_order_relaxed); } + + protected: + std::atomic mDirty{ true }; + std::atomic mMicrophoneEnergy{ 0.0f }; + std::atomic mGain{ 0.0f }; +}; + +using LLCustomProcessorStatePtr = std::shared_ptr; + // Used to process/retrieve audio levels after // all of the processing (AGC, AEC, etc.) for display in-world to the user. class LLCustomProcessor : public webrtc::CustomProcessing { - public: - LLCustomProcessor(); +public: + LLCustomProcessor(LLCustomProcessorStatePtr state); ~LLCustomProcessor() override {} // (Re-) Initializes the submodule. void Initialize(int sample_rate_hz, int num_channels) override; // Analyzes the given capture or render signal. - void Process(webrtc::AudioBuffer *audio) override; + void Process(webrtc::AudioBuffer* audio) override; // Returns a string representation of the module state. std::string ToString() const override { return ""; } - float getMicrophoneEnergy() { return mMicrophoneEnergy; } - - void setGain(float gain) { mGain = gain; } - - protected: - static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing - int mSampleRateHz; - int mNumChannels; +protected: + static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing + int mSampleRateHz{ 48000 }; + int mNumChannels{ 2 }; + int mRampFrames{ 2 }; + float mCurrentGain{ 0.0f }; + float mGainStep{ 0.0f }; float mSumVector[NUM_PACKETS_TO_FILTER]; - float mMicrophoneEnergy; - float mGain; + friend LLCustomProcessorState; + LLCustomProcessorStatePtr mState; }; // Primary singleton implementation for interfacing // with the native webrtc library. -class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceSink +class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceObserver { public: LLWebRTCImpl(LLWebRTCLogCallback* logCallback); ~LLWebRTCImpl() { delete mLogSink; + + // Explicit cleanup for the sake of debugging and crash stacks + mPeerCustomProcessor = nullptr; } void init(); @@ -214,10 +448,15 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS float getTuningAudioLevel() override; float getPeerConnectionAudioLevel() override; - void setPeerConnectionGain(float gain) override; + void setMicGain(float gain) override; + void setTuningMicGain(float gain) override; + + void setMute(bool mute, int delay_ms = 20) override; + + void intSetMute(bool mute, int delay_ms = 20); // - // AudioDeviceSink + // AudioDeviceObserver // void OnDevicesUpdated() override; @@ -246,19 +485,19 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS mNetworkThread->PostTask(std::move(task), location); } - void WorkerBlockingCall(rtc::FunctionView functor, + void WorkerBlockingCall(webrtc::FunctionView functor, const webrtc::Location& location = webrtc::Location::Current()) { mWorkerThread->BlockingCall(std::move(functor), location); } - void SignalingBlockingCall(rtc::FunctionView functor, + void SignalingBlockingCall(webrtc::FunctionView functor, const webrtc::Location& location = webrtc::Location::Current()) { mSignalingThread->BlockingCall(std::move(functor), location); } - void NetworkBlockingCall(rtc::FunctionView functor, + void NetworkBlockingCall(webrtc::FunctionView functor, const webrtc::Location& location = webrtc::Location::Current()) { mNetworkThread->BlockingCall(std::move(functor), location); @@ -266,7 +505,7 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS // Allows the LLWebRTCPeerConnectionImpl class to retrieve the // native webrtc PeerConnectionFactory. - rtc::scoped_refptr getPeerConnectionFactory() + webrtc::scoped_refptr getPeerConnectionFactory() { return mPeerConnectionFactory; } @@ -275,49 +514,47 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS LLWebRTCPeerConnectionInterface* newPeerConnection(); void freePeerConnection(LLWebRTCPeerConnectionInterface* peer_connection); - // enables/disables capture via the capture device - void setRecording(bool recording); - - void setPlayout(bool playing); - protected: + + void workerDeployDevices(); LLWebRTCLogSink* mLogSink; // The native webrtc threads - std::unique_ptr mNetworkThread; - std::unique_ptr mWorkerThread; - std::unique_ptr mSignalingThread; + std::unique_ptr mNetworkThread; + std::unique_ptr mWorkerThread; + std::unique_ptr mSignalingThread; // The factory that allows creation of native webrtc PeerConnections. - rtc::scoped_refptr mPeerConnectionFactory; + webrtc::scoped_refptr mPeerConnectionFactory; - rtc::scoped_refptr mAudioProcessingModule; + webrtc::scoped_refptr mAudioProcessingModule; // more native webrtc stuff - std::unique_ptr mTaskQueueFactory; + std::unique_ptr mTaskQueueFactory; // Devices void updateDevices(); - rtc::scoped_refptr mTuningDeviceModule; - rtc::scoped_refptr mPeerDeviceModule; + void deployDevices(); + std::atomic mDevicesDeploying; + webrtc::scoped_refptr mDeviceModule; std::vector mVoiceDevicesObserverList; // accessors in native webrtc for devices aren't apparently implemented yet. bool mTuningMode; - int32_t mRecordingDevice; + std::string mRecordingDevice; LLWebRTCVoiceDeviceList mRecordingDeviceList; - int32_t mPlayoutDevice; + std::string mPlayoutDevice; LLWebRTCVoiceDeviceList mPlayoutDeviceList; bool mMute; + float mGain; - LLAudioDeviceObserver * mTuningAudioDeviceObserver; - LLCustomProcessor * mPeerCustomProcessor; + LLCustomProcessorStatePtr mPeerCustomProcessor; // peer connections - std::vector> mPeerConnections; + std::vector> mPeerConnections; }; @@ -342,7 +579,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, void terminate(); virtual void AddRef() const override = 0; - virtual rtc::RefCountReleaseStatus Release() const override = 0; + virtual webrtc::RefCountReleaseStatus Release() const override = 0; // // LLWebRTCPeerConnection @@ -373,10 +610,10 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, // void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override {} - void OnAddTrack(rtc::scoped_refptr receiver, - const std::vector> &streams) override; - void OnRemoveTrack(rtc::scoped_refptr receiver) override; - void OnDataChannel(rtc::scoped_refptr channel) override; + void OnAddTrack(webrtc::scoped_refptr receiver, + const std::vector> &streams) override; + void OnRemoveTrack(webrtc::scoped_refptr receiver) override; + void OnDataChannel(webrtc::scoped_refptr channel) override; void OnRenegotiationNeeded() override {} void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override {}; void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override; @@ -415,7 +652,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, LLWebRTCImpl * mWebRTCImpl; - rtc::scoped_refptr mPeerConnectionFactory; + webrtc::scoped_refptr mPeerConnectionFactory; typedef enum { MUTE_INITIAL, @@ -429,12 +666,14 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, std::vector> mCachedIceCandidates; bool mAnswerReceived; - rtc::scoped_refptr mPeerConnection; - rtc::scoped_refptr mLocalStream; + webrtc::scoped_refptr mPeerConnection; + webrtc::scoped_refptr mLocalStream; // data std::vector mDataObserverList; - rtc::scoped_refptr mDataChannel; + webrtc::scoped_refptr mDataChannel; + + std::atomic mPendingJobs; }; } diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 5bfac34ca55..08b3df87abe 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -63,8 +63,8 @@ set(llwindow_LINK_LIBRARIES # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level if (LINUX) - list(APPEND viewer_SOURCE_FILES - llkeyboardsdl.cpp + list(APPEND viewer_SOURCE_FILES + llkeyboardsdl.cpp llwindowsdl.cpp ) list(APPEND viewer_HEADER_FILES @@ -107,7 +107,7 @@ if (DARWIN) llkeyboardmacosx.cpp llwindowmacosx.cpp PROPERTIES - COMPILE_FLAGS "-Wno-deprecated-declarations -fpascal-strings" + COMPILE_FLAGS "-fpascal-strings" ) endif (DARWIN) @@ -180,8 +180,7 @@ endif (SDL_FOUND) target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) - + if (DARWIN) - find_library(CARBON_LIBRARY Carbon) target_link_libraries(llwindow ${CARBON_LIBRARY}) endif (DARWIN) diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 387982dfc28..ff85b2cb148 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -312,7 +312,7 @@ std::string get_string(IDxDiagContainer *containerp, const WCHAR *wszPropName) WCHAR wszPropValue[256]; get_wstring(containerp, wszPropName, wszPropValue, 256); - return utf16str_to_utf8str(wszPropValue); + return ll_convert(std::wstring(wszPropValue)); } LLDXHardware::LLDXHardware() @@ -440,7 +440,7 @@ LLSD LLDXHardware::getDisplayInfo() // print the value // windows doesn't guarantee to be null terminated release_version[RV_SIZE - 1] = NULL; - ret["DriverVersion"] = utf16str_to_utf8str(release_version); + ret["DriverVersion"] = ll_convert(std::wstring(release_version)); } RegCloseKey(hKey); diff --git a/indra/llwindow/llopenglview-objc.h b/indra/llwindow/llopenglview-objc.h index 97f41254840..028549b82ec 100644 --- a/indra/llwindow/llopenglview-objc.h +++ b/indra/llwindow/llopenglview-objc.h @@ -42,7 +42,6 @@ unsigned int mMarkedTextLength; bool mMarkedTextAllowed; bool mSimulatedRightClick; - bool mOldResize; } - (id) initWithSamples:(NSUInteger)samples; - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync; @@ -50,8 +49,6 @@ - (void)commitCurrentPreedit; -- (void) setOldResize:(bool)oldresize; - // rebuildContext // Destroys and recreates a context with the view's internal format set via setPixelFormat; // Use this in event of needing to rebuild a context for whatever reason, without needing to assign a new pixel format. @@ -68,7 +65,6 @@ - (unsigned long) getVramSize; - (void) allowMarkedTextInput:(bool)allowed; -- (void) viewDidEndLiveResize; @end @@ -88,9 +84,6 @@ @interface LLNSWindow : NSWindow -- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view; -- (NSPoint)flipPoint:(NSPoint)aPoint; - @end @interface NSScreen (PointConversion) @@ -100,16 +93,6 @@ */ + (NSScreen *)currentScreenForMouseLocation; -/* - Allows you to convert a point from global coordinates to the current screen coordinates. - */ -- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint; - -/* - Allows to flip the point coordinates, so y is 0 at the top instead of the bottom. x remains the same - */ -- (NSPoint)flipPoint:(NSPoint)aPoint; - @end #endif diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 937c3c7a6e7..c9a62eedb1c 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -28,6 +28,8 @@ #import "llwindowmacosx-objc.h" #import "llappdelegate-objc.h" +#import + extern BOOL gHiDPISupport; #pragma mark local functions @@ -64,16 +66,16 @@ attributedStringInfo getSegments(NSAttributedString *str) segment_standouts seg_standouts; NSRange effectiveRange; NSRange limitRange = NSMakeRange(0, [str length]); - + while (limitRange.length > 0) { NSNumber *attr = [str attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange]; limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange)); - + if (effectiveRange.length <= 0) { effectiveRange.length = 1; } - + if ([attr integerValue] == 2) { seg_lengths.push_back(effectiveRange.length); @@ -96,43 +98,19 @@ @implementation NSScreen (PointConversion) + (NSScreen *)currentScreenForMouseLocation { NSPoint mouseLocation = [NSEvent mouseLocation]; - + NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator]; NSScreen *screen; while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(mouseLocation, screen.frame, NO)) ; - - return screen; -} - -- (NSPoint)convertPointToScreenCoordinates:(NSPoint)aPoint -{ - float normalizedX = fabs(fabs(self.frame.origin.x) - fabs(aPoint.x)); - float normalizedY = aPoint.y - self.frame.origin.y; - - return NSMakePoint(normalizedX, normalizedY); -} - -- (NSPoint)flipPoint:(NSPoint)aPoint -{ - return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y); + return screen; } @end @implementation LLOpenGLView -// Force a high quality update after live resizing -- (void) viewDidEndLiveResize -{ - if (mOldResize) //Maint-3135 - { - NSSize size = [self frame].size; - callResize(size.width, size.height); - } -} - - (unsigned long)getVramSize { CGLRendererInfoObj info = 0; @@ -153,7 +131,7 @@ - (unsigned long)getVramSize { vram_megabytes = 256; } - + return (unsigned long)vram_megabytes; // return value is in megabytes. } @@ -162,15 +140,15 @@ - (void)viewDidMoveToWindow [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowResized:) name:NSWindowDidResizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillMiniaturize:) name:NSWindowWillMiniaturizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidDeminiaturize:) name:NSWindowDidDeminiaturizeNotification object:[self window]]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:[self window]]; @@ -187,18 +165,10 @@ - (void)viewDidMoveToWindow } } -- (void)setOldResize:(bool)oldresize -{ - mOldResize = oldresize; -} - - (void)windowResized:(NSNotification *)notification; { - if (!mOldResize) //Maint-3288 - { - NSSize dev_sz = gHiDPISupport ? [self convertSizeToBacking:[self frame].size] : [self frame].size; - callResize(dev_sz.width, dev_sz.height); - } + NSSize dev_sz = [self convertSizeToBacking:[self frame].size]; + callResize(dev_sz.width, dev_sz.height); } - (void)windowWillMiniaturize:(NSNotification *)notification; @@ -242,11 +212,17 @@ - (id) initWithSamples:(NSUInteger)samples andVsync:(BOOL)vsync return [self initWithFrame:[self bounds] withSamples:samples andVsync:vsync]; } +#if LL_DARWIN +// For setView and opengl deprecation +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOOL)vsync { - [self registerForDraggedTypes:[NSArray arrayWithObject:NSURLPboardType]]; + [self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeURL]]; [self initWithFrame:frame]; - + // Initialize with a default "safe" pixel format that will work with versions dating back to OS X 10.6. // Any specialized pixel formats, i.e. a core profile pixel format, should be initialized through rebuildContextWithFormat. // 10.7 and 10.8 don't really care if we're defining a profile or not. If we don't explicitly request a core or legacy profile, it'll always assume a legacy profile (for compatibility reasons). @@ -255,8 +231,8 @@ - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOO NSOpenGLPFADoubleBuffer, NSOpenGLPFAClosestPolicy, NSOpenGLPFAAccelerated, - NSOpenGLPFASampleBuffers, static_cast(samples > 0 ? 1 : 0), - NSOpenGLPFASamples, static_cast(samples), + NSOpenGLPFASampleBuffers, 0, + NSOpenGLPFASamples, 0, NSOpenGLPFAStencilSize, 8, NSOpenGLPFADepthSize, 24, NSOpenGLPFAAlphaSize, 8, @@ -264,48 +240,46 @@ - (id) initWithFrame:(NSRect)frame withSamples:(NSUInteger)samples andVsync:(BOO NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core, 0 }; - + NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease]; - + if (pixelFormat == nil) { NSLog(@"Failed to create pixel format!", nil); return nil; } - + NSOpenGLContext *glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - + if (glContext == nil) { NSLog(@"Failed to create OpenGL context!", nil); return nil; } - + [self setPixelFormat:pixelFormat]; //for retina support [self setWantsBestResolutionOpenGLSurface:gHiDPISupport]; [self setOpenGLContext:glContext]; - + [glContext setView:self]; - + [glContext makeCurrentContext]; - + if (vsync) { GLint value = 1; - [glContext setValues:&value forParameter:NSOpenGLCPSwapInterval]; + [glContext setValues:&value forParameter:NSOpenGLContextParameterSwapInterval]; } else { // supress this error after move to Xcode 7: // error: null passed to a callee that requires a non-null argument [-Werror,-Wnonnull] // Tried using ObjC 'nonnull' keyword as per SO article but didn't build GLint swapInterval=0; - [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; + [glContext setValues:&swapInterval forParameter:NSOpenGLContextParameterSwapInterval]; } - - mOldResize = false; - + return self; } @@ -317,22 +291,26 @@ - (BOOL) rebuildContext - (BOOL) rebuildContextWithFormat:(NSOpenGLPixelFormat *)format { NSOpenGLContext *ctx = [self openGLContext]; - + [ctx clearDrawable]; [ctx initWithFormat:format shareContext:nil]; - + if (ctx == nil) { NSLog(@"Failed to create OpenGL context!", nil); return false; } - + [self setOpenGLContext:ctx]; [ctx setView:self]; [ctx makeCurrentContext]; return true; } +#if LL_DARWIN +#pragma clang diagnostic pop +#endif + - (CGLContextObj)getCGLContextObj { NSOpenGLContext *ctx = [self openGLContext]; @@ -350,18 +328,14 @@ - (CGLPixelFormatObj*)getCGLPixelFormatObj - (void) mouseDown:(NSEvent *)theEvent { - NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; - // Apparently people still use this? - if ([theEvent modifierFlags] & NSCommandKeyMask && - !([theEvent modifierFlags] & NSControlKeyMask) && - !([theEvent modifierFlags] & NSShiftKeyMask) && - !([theEvent modifierFlags] & NSAlternateKeyMask) && - !([theEvent modifierFlags] & NSAlphaShiftKeyMask) && - !([theEvent modifierFlags] & NSFunctionKeyMask) && - !([theEvent modifierFlags] & NSHelpKeyMask)) + if ([theEvent modifierFlags] & NSEventModifierFlagCommand && + !([theEvent modifierFlags] & NSEventModifierFlagControl) && + !([theEvent modifierFlags] & NSEventModifierFlagShift) && + !([theEvent modifierFlags] & NSEventModifierFlagOption) && + !([theEvent modifierFlags] & NSEventModifierFlagCapsLock) && + !([theEvent modifierFlags] & NSEventModifierFlagFunction) && + !([theEvent modifierFlags] & NSEventModifierFlagHelp)) { callRightMouseDown(mMousePos, [theEvent modifierFlags]); mSimulatedRightClick = true; @@ -382,7 +356,7 @@ - (void) mouseUp:(NSEvent *)theEvent callRightMouseUp(mMousePos, [theEvent modifierFlags]); mSimulatedRightClick = false; } else { - NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; + NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; callLeftMouseUp(mMousePos, [theEvent modifierFlags]); @@ -391,32 +365,26 @@ - (void) mouseUp:(NSEvent *)theEvent - (void) rightMouseDown:(NSEvent *)theEvent { - NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; callRightMouseDown(mMousePos, [theEvent modifierFlags]); } - (void) rightMouseUp:(NSEvent *)theEvent { - NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; callRightMouseUp(mMousePos, [theEvent modifierFlags]); } - (void)mouseMoved:(NSEvent *)theEvent { - NSPoint dev_delta = gHiDPISupport ? [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])] : NSMakePoint([theEvent deltaX], [theEvent deltaY]); + NSPoint dev_delta = [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])]; float mouseDeltas[] = { float(dev_delta.x), float(dev_delta.y) }; - + callDeltaUpdate(mouseDeltas, 0); - - NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; + + NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; callMouseMoved(mMousePos, 0); @@ -431,16 +399,16 @@ - (void) mouseDragged:(NSEvent *)theEvent // The old CoreGraphics APIs we previously relied on are now flagged as obsolete. // NSEvent isn't obsolete, and provides us with the correct deltas. - NSPoint dev_delta = gHiDPISupport ? [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])] : NSMakePoint([theEvent deltaX], [theEvent deltaY]); + NSPoint dev_delta = [self convertPointToBacking:NSMakePoint([theEvent deltaX], [theEvent deltaY])]; float mouseDeltas[] = { float(dev_delta.x), float(dev_delta.y) }; - + callDeltaUpdate(mouseDeltas, 0); - - NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; + + NSPoint mPoint = [self convertPointToBacking:[theEvent locationInWindow]]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; callMouseDragged(mMousePos, 0); @@ -448,17 +416,11 @@ - (void) mouseDragged:(NSEvent *)theEvent - (void) otherMouseDown:(NSEvent *)theEvent { - NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; callOtherMouseDown(mMousePos, [theEvent modifierFlags], [theEvent buttonNumber]); } - (void) otherMouseUp:(NSEvent *)theEvent { - NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; - mMousePos[0] = mPoint.x; - mMousePos[1] = mPoint.y; callOtherMouseUp(mMousePos, [theEvent modifierFlags], [theEvent buttonNumber]); } @@ -469,7 +431,7 @@ - (void) rightMouseDragged:(NSEvent *)theEvent - (void) otherMouseDragged:(NSEvent *)theEvent { - [self mouseDragged:theEvent]; + [self mouseDragged:theEvent]; } - (void) scrollWheel:(NSEvent *)theEvent @@ -493,7 +455,7 @@ - (void) keyDown:(NSEvent *)theEvent { NativeKeyEventData eventData = extractKeyDataFromKeyEvent(theEvent); eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; - + uint keycode = [theEvent keyCode]; // We must not depend on flagsChange event to detect modifier flags changed, // must depend on the modifire flags in the event parameter. @@ -511,7 +473,7 @@ - (void) keyDown:(NSEvent *)theEvent if (acceptsText && !mMarkedTextAllowed && - !(mModifiers & (NSControlKeyMask | NSCommandKeyMask)) && // commands don't invoke InputWindow + !(mModifiers & (NSEventModifierFlagControl | NSEventModifierFlagCommand)) && // commands don't invoke InputWindow ![(LLAppDelegate*)[NSApp delegate] romanScript] && ch > ' ' && ch != NSDeleteCharacter && @@ -527,26 +489,26 @@ - (void) keyDown:(NSEvent *)theEvent - (void)flagsChanged:(NSEvent *)theEvent { NativeKeyEventData eventData = extractKeyDataFromModifierEvent(theEvent); - + mModifiers = [theEvent modifierFlags]; callModifier([theEvent modifierFlags]); - + NSInteger mask = 0; switch([theEvent keyCode]) - { - case 56: - mask = NSShiftKeyMask; + { + case kVK_Shift: + mask = NSEventModifierFlagShift; break; - case 58: - mask = NSAlternateKeyMask; + case kVK_Option: + mask = NSEventModifierFlagOption; break; - case 59: - mask = NSControlKeyMask; + case kVK_Control: + mask = NSEventModifierFlagControl; break; default: - return; + return; } - + if (mModifiers & mask) { eventData.mKeyEvent = NativeKeyEventData::KEYDOWN; @@ -565,7 +527,7 @@ - (void)flagsChanged:(NSEvent *)theEvent { eventData.mKeyEvent = NativeKeyEventData::KEYUP; callKeyUp(&eventData, [theEvent keyCode], 0); - } + } } - (BOOL) acceptsFirstResponder @@ -577,12 +539,12 @@ - (NSDragOperation) draggingEntered:(id)sender { NSPasteboard *pboard; NSDragOperation sourceDragMask; - + sourceDragMask = [sender draggingSourceOperationMask]; - + pboard = [sender draggingPasteboard]; - - if ([[pboard types] containsObject:NSURLPboardType]) + + if ([[pboard types] containsObject:NSPasteboardTypeURL]) { if (sourceDragMask & NSDragOperationLink) { NSURL *fileUrl = [[pboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]] options:[NSDictionary dictionary]] objectAtIndex:0]; @@ -596,7 +558,7 @@ - (NSDragOperation) draggingEntered:(id)sender - (NSDragOperation)draggingUpdated:(id )sender { callHandleDragUpdated(mLastDraggedUrl); - + return NSDragOperationLink; } @@ -650,12 +612,12 @@ - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replaceme unsigned(selectedRange.location), unsigned(selectedRange.length) }; - + unsigned int replacement[2] = { unsigned(replacementRange.location), unsigned(replacementRange.length) }; - + int string_length = [aString length]; unichar *text = new unichar[string_length]; attributedStringInfo segments; @@ -695,6 +657,12 @@ - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replaceme } } +#if LL_DARWIN +// For commitEditing deprecation +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + - (void)commitCurrentPreedit { if (mHasMarkedText) @@ -706,6 +674,10 @@ - (void)commitCurrentPreedit } } +#if LL_DARWIN +#pragma clang diagnostic pop +#endif + - (void)unmarkText { [[self inputContext] discardMarkedText]; @@ -756,7 +728,7 @@ - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange return; } } - + @try { if (!mHasMarkedText) @@ -769,7 +741,7 @@ - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange resetPreedit(); // We may never get this point since unmarkText may be called before insertText ever gets called once we submit our text. // But just in case... - + for (NSInteger i = 0; i < [aString length]; i++) { handleUnicodeCharacter([aString characterAtIndex:i]); @@ -785,9 +757,9 @@ - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange - (void) insertNewline:(id)sender { - if (!(mModifiers & NSCommandKeyMask) && - !(mModifiers & NSShiftKeyMask) && - !(mModifiers & NSAlternateKeyMask)) + if (!(mModifiers & NSEventModifierFlagCommand) && + !(mModifiers & NSEventModifierFlagShift) && + !(mModifiers & NSEventModifierFlagOption)) { callUnicodeCallback(13, 0); } else { @@ -906,27 +878,6 @@ - (id) init return self; } -- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view -{ - NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation]; - if(currentScreen) - { - NSPoint windowPoint = [view convertPoint:point toView:nil]; - NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint]; - NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint]; - flippedScreenPoint.y += [currentScreen frame].origin.y; - - return flippedScreenPoint; - } - - return NSZeroPoint; -} - -- (NSPoint)flipPoint:(NSPoint)aPoint -{ - return NSMakePoint(aPoint.x, self.frame.size.height - aPoint.y); -} - - (BOOL) becomeFirstResponder { callFocus(); diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 151028113ae..d0fa16b26a6 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -147,7 +147,6 @@ class LLWindow : public LLInstanceTracker virtual void swapBuffers() = 0; virtual void bringToFront() = 0; virtual void focusClient() { }; // this may not have meaning or be required on other platforms, therefore, it's not abstract - virtual void setOldResize(bool oldresize) { }; // handy coordinate space conversion routines // NB: screen to window and vice verse won't work on width/height coordinate pairs, // as the conversion must take into account left AND right border widths, etc. diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index 195f68e08be..7331f50ba0c 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -68,7 +68,13 @@ void LLWindowCallbacks::handleMouseLeave(LLWindow *window) return; } -bool LLWindowCallbacks::handleCloseRequest(LLWindow *window) +bool LLWindowCallbacks::handleCloseRequest(LLWindow *window, bool from_user) +{ + //allow the window to close + return true; +} + +bool LLWindowCallbacks::handleSessionExit(LLWindow* window) { //allow the window to close return true; diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index d812f935244..59dcdd3adee 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -42,7 +42,8 @@ class LLWindowCallbacks virtual bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); virtual void handleMouseLeave(LLWindow *window); // return true to allow window to close, which will then cause handleQuit to be called - virtual bool handleCloseRequest(LLWindow *window); + virtual bool handleCloseRequest(LLWindow *window, bool from_user); + virtual bool handleSessionExit(LLWindow* window); // window is about to be destroyed, clean up your business virtual void handleQuit(LLWindow *window); virtual bool handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index d9d8bfce1fe..b302a705da6 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -100,7 +100,6 @@ bool isCGCursorVisible(); void hideNSCursorTillMove(bool hide); void requestUserAttention(); long showAlert(std::string title, std::string text, int type); -void setResizeMode(bool oldresize, void* glview); NSWindowRef createNSWindow(int x, int y, int width, int height); @@ -111,16 +110,14 @@ void glSwapBuffers(void* context); CGLContextObj getCGLContextObj(GLViewRef view); unsigned long getVramSize(GLViewRef view); float getDeviceUnitSize(GLViewRef view); -CGPoint getContentViewBoundsPosition(NSWindowRef window); -CGSize getContentViewBoundsSize(NSWindowRef window); -CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view); +CGRect getContentViewRect(NSWindowRef window); +CGRect getBackingViewRect(NSWindowRef window, GLViewRef view); void getWindowSize(NSWindowRef window, float* size); void setWindowSize(NSWindowRef window, int width, int height); void getCursorPos(NSWindowRef window, float* pos); void makeWindowOrderFront(NSWindowRef window); void convertScreenToWindow(NSWindowRef window, float *coord); void convertWindowToScreen(NSWindowRef window, float *coord); -void convertScreenToView(NSWindowRef window, float *coord); void convertRectToScreen(NSWindowRef window, float *coord); void convertRectFromScreen(NSWindowRef window, float *coord); void setWindowPos(NSWindowRef window, float* pos); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 2e75d309ea6..42cd95be5dd 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -162,11 +162,21 @@ void showNSCursor() [NSCursor unhide]; } +#if LL_DARWIN +// For CGCursorIsVisible no replacement in modern API +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + bool isCGCursorVisible() { return CGCursorIsVisible(); } +#if LL_DARWIN +#pragma clang diagnostic pop +#endif + void hideNSCursorTillMove(bool hide) { [NSCursor setHiddenUntilMouseMoves:hide]; @@ -213,7 +223,8 @@ OSErr setImageCursor(CursorRef ref) NSWindowRef createNSWindow(int x, int y, int width, int height) { LLNSWindow *window = [[LLNSWindow alloc]initWithContentRect:NSMakeRect(x, y, width, height) - styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO]; + styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable + backing:NSBackingStoreBuffered defer:NO]; [window makeKeyAndOrderFront:nil]; [window setAcceptsMouseMovedEvents:TRUE]; [window setRestorable:FALSE]; // Viewer manages state from own settings @@ -227,11 +238,6 @@ GLViewRef createOpenGLView(NSWindowRef window, unsigned int samples, bool vsync) return glview; } -void setResizeMode(bool oldresize, void* glview) -{ - [(LLOpenGLView *)glview setOldResize:oldresize]; -} - void glSwapBuffers(void* context) { [(NSOpenGLContext*)context flushBuffer]; @@ -258,19 +264,14 @@ float getDeviceUnitSize(GLViewRef view) return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width; } -CGPoint getContentViewBoundsPosition(NSWindowRef window) +CGRect getContentViewRect(NSWindowRef window) { - return [[(LLNSWindow*)window contentView] bounds].origin; + return [[(LLNSWindow*)window contentView] bounds]; } -CGSize getContentViewBoundsSize(NSWindowRef window) +CGRect getBackingViewRect(NSWindowRef window, GLViewRef view) { - return [[(LLNSWindow*)window contentView] bounds].size; -} - -CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view) -{ - return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]].size; + return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]]; } void getWindowSize(NSWindowRef window, float* size) @@ -313,9 +314,7 @@ void makeWindowOrderFront(NSWindowRef window) void convertScreenToWindow(NSWindowRef window, float *coord) { - NSRect point; - point.origin.x = coord[0]; - point.origin.y = coord[1]; + NSRect point = NSMakeRect(coord[0], coord[1], 0,0); point = [(LLNSWindow*)window convertRectFromScreen:point]; coord[0] = point.origin.x; coord[1] = point.origin.y; @@ -323,28 +322,18 @@ void convertScreenToWindow(NSWindowRef window, float *coord) void convertRectToScreen(NSWindowRef window, float *coord) { - NSRect point; - point.origin.x = coord[0]; - point.origin.y = coord[1]; - point.size.width = coord[2]; - point.size.height = coord[3]; - - point = [(LLNSWindow*)window convertRectToScreen:point]; - - coord[0] = point.origin.x; - coord[1] = point.origin.y; - coord[2] = point.size.width; - coord[3] = point.size.height; + NSRect rect = NSMakeRect(coord[0], coord[1], coord[2], coord[3]);; + rect = [(LLNSWindow*)window convertRectToScreen:rect]; + + coord[0] = rect.origin.x; + coord[1] = rect.origin.y; + coord[2] = rect.size.width; + coord[3] = rect.size.height; } void convertRectFromScreen(NSWindowRef window, float *coord) { - NSRect point; - point.origin.x = coord[0]; - point.origin.y = coord[1]; - point.size.width = coord[2]; - point.size.height = coord[3]; - + NSRect point = NSMakeRect(coord[0], coord[1], coord[2], coord[3]); point = [(LLNSWindow*)window convertRectFromScreen:point]; coord[0] = point.origin.x; @@ -353,23 +342,13 @@ void convertRectFromScreen(NSWindowRef window, float *coord) coord[3] = point.size.height; } -void convertScreenToView(NSWindowRef window, float *coord) -{ - NSRect point; - point.origin.x = coord[0]; - point.origin.y = coord[1]; - point.origin = [(LLNSWindow*)window convertScreenToBase:point.origin]; - point.origin = [[(LLNSWindow*)window contentView] convertPoint:point.origin fromView:nil]; -} - void convertWindowToScreen(NSWindowRef window, float *coord) { - NSPoint point; - point.x = coord[0]; - point.y = coord[1]; - point = [(LLNSWindow*)window convertToScreenFromLocalPoint:point relativeToView:[(LLNSWindow*)window contentView]]; - coord[0] = point.x; - coord[1] = point.y; + NSRect rect = NSMakeRect(coord[0], coord[1], 0, 0); + rect = [(LLNSWindow*)window convertRectToScreen:rect]; + + coord[0] = rect.origin.x; + coord[1] = [[NSScreen screens][0] frame].size.height - rect.origin.y; } void closeWindow(NSWindowRef window) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index dadbc83f45e..e37fe116711 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -610,7 +610,7 @@ void callQuitHandler() { if (gWindowImplementation && gWindowImplementation->getCallbacks()) { - if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) + if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation, true)) { gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); } @@ -985,7 +985,7 @@ bool LLWindowMacOSX::getPosition(LLCoordScreen *position) } else if(mWindow) { - const CGPoint & pos = getContentViewBoundsPosition(mWindow); + CGPoint pos = getContentViewRect(mWindow).origin; position->mX = pos.x; position->mY = pos.y; @@ -1012,7 +1012,7 @@ bool LLWindowMacOSX::getSize(LLCoordScreen *size) } else if(mWindow) { - const CGSize & sz = gHiDPISupport ? getDeviceContentViewSize(mWindow, mGLView) : getContentViewBoundsSize(mWindow); + CGSize sz = getBackingViewRect(mWindow, mGLView).size; size->mX = sz.width; size->mY = sz.height; @@ -1038,7 +1038,7 @@ bool LLWindowMacOSX::getSize(LLCoordWindow *size) } else if(mWindow) { - const CGSize & sz = gHiDPISupport ? getDeviceContentViewSize(mWindow, mGLView) : getContentViewBoundsSize(mWindow); + CGSize sz = getBackingViewRect(mWindow, mGLView).size; size->mX = sz.width; size->mY = sz.height; @@ -1224,6 +1224,12 @@ void LLWindowMacOSX::setMouseClipping( bool b ) adjustCursorDecouple(); } +#if LL_DARWIN +// For CGSetLocalEventsSuppressionInterval there is no replacement in modern API +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + bool LLWindowMacOSX::setCursorPosition(const LLCoordWindow position) { bool result = false; @@ -1261,6 +1267,10 @@ bool LLWindowMacOSX::setCursorPosition(const LLCoordWindow position) return result; } +#if LL_DARWIN +#pragma clang diagnostic pop +#endif + bool LLWindowMacOSX::getCursorPosition(LLCoordWindow *position) { float cursor_point[2]; @@ -1485,8 +1495,9 @@ bool LLWindowMacOSX::convertCoords(LLCoordScreen from, LLCoordWindow* to) convertScreenToWindow(mWindow, mouse_point); - to->mX = mouse_point[0]; - to->mY = mouse_point[1]; + float scale_factor = getSystemUISize(); + to->mX = mouse_point[0] * scale_factor; + to->mY = mouse_point[1] * scale_factor; return true; } @@ -1498,9 +1509,9 @@ bool LLWindowMacOSX::convertCoords(LLCoordWindow from, LLCoordScreen *to) if(mWindow) { float mouse_point[2]; - - mouse_point[0] = from.mX; - mouse_point[1] = from.mY; + float scale_factor = getSystemUISize(); + mouse_point[0] = from.mX / scale_factor; + mouse_point[1] = from.mY / scale_factor; convertWindowToScreen(mWindow, mouse_point); @@ -2637,7 +2648,7 @@ MASK LLWindowMacOSX::modifiersToMask(S16 modifiers) F32 LLWindowMacOSX::getSystemUISize() { - return gHiDPISupport ? ::getDeviceUnitSize(mGLView) : LLWindow::getSystemUISize(); + return ::getDeviceUnitSize(mGLView); } #if LL_OS_DRAGDROP_ENABLED diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 7de1a40d93d..110c5756d0f 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -174,9 +174,6 @@ class LLWindowMacOSX : public LLWindow bool shouldPostQuit() { return mPostQuit; } - //Satisfy MAINT-3135 and MAINT-3288 with a flag. - /*virtual */ void setOldResize(bool oldresize) override {setResizeMode(oldresize, mGLView); } - private: void restoreGLContext(); diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 7433ad6bd27..05be319c0b3 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1881,7 +1881,7 @@ void LLWindowSDL::gatherInput() { // *FIX: More informative dialog? LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL; - if(mCallbacks->handleCloseRequest(this)) + if(mCallbacks->handleCloseRequest(this, false)) { // Get the app to initiate cleanup. mCallbacks->handleQuit(this); @@ -1931,7 +1931,7 @@ void LLWindowSDL::gatherInput() break; case SDL_QUIT: - if(mCallbacks->handleCloseRequest(this)) + if(mCallbacks->handleCloseRequest(this, true)) { // Get the app to initiate cleanup. mCallbacks->handleQuit(this); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index b127c9b48fb..23d58667104 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -810,7 +810,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, // } // SL-12971 dual GPU display - DISPLAY_DEVICEA display_device; + DISPLAY_DEVICE display_device; int display_index = -1; DWORD display_flags = 0; // EDD_GET_DEVICE_INTERFACE_NAME ? const size_t display_bytes = sizeof(display_device); @@ -821,23 +821,23 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, { // CHAR DeviceName [ 32] Adapter name // CHAR DeviceString[128] - CHAR text[256]; + WCHAR text[256]; - size_t name_len = strlen(display_device.DeviceName ); - size_t desc_len = strlen(display_device.DeviceString); + size_t name_len = lstrlen(display_device.DeviceName ); + size_t desc_len = lstrlen(display_device.DeviceString); - const CHAR *name = name_len ? display_device.DeviceName : "???"; - const CHAR *desc = desc_len ? display_device.DeviceString : "???"; + const WCHAR *name = name_len ? display_device.DeviceName : TEXT("???"); + const WCHAR *desc = desc_len ? display_device.DeviceString : TEXT("???"); - sprintf(text, "Display Device %d: %s, %s", display_index, name, desc); - LL_INFOS("Window") << text << LL_ENDL; + wsprintf(text, TEXT("Display Device %d: %s, %s"), display_index, name, desc); + LL_INFOS("Window") << ll_convert(std::wstring(text)) << LL_ENDL; } ::ZeroMemory(&display_device,display_bytes); display_device.cb = display_bytes; display_index++; - } while( EnumDisplayDevicesA(NULL, display_index, &display_device, display_flags )); + } while( EnumDisplayDevices(NULL, display_index, &display_device, display_flags )); LL_INFOS("Window") << "Total Display Devices: " << display_index << LL_ENDL; @@ -1696,6 +1696,11 @@ const S32 max_format = (S32)num_formats - 1; return false; } + // Setup Tracy gpu context + { + LL_PROFILER_GPU_CONTEXT; + } + // Disable vertical sync for swap toggleVSync(enable_vsync); @@ -1727,8 +1732,6 @@ const S32 max_format = (S32)num_formats - 1; swapBuffers(); } - LL_PROFILER_GPU_CONTEXT; - return true; } @@ -1961,7 +1964,7 @@ void LLWindowWin32::setTitle(const std::string title) // to support non-ascii usernames (and region names?) mWindowThread->post([=]() { - SetWindowTextA(mWindowHandle, title.c_str()); + SetWindowText(mWindowHandle, ll_convert(title).c_str()); }); } @@ -2461,10 +2464,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_CLOSE: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_CLOSE"); + // todo: WM_CLOSE can be caused by user and by task manager, + // distinguish these cases. + // For now assume it is always user. window_imp->post([=]() { // Will the app allow the window to close? - if (window_imp->mCallbacks->handleCloseRequest(window_imp)) + if (window_imp->mCallbacks->handleCloseRequest(window_imp, true)) { // Get the app to initiate cleanup. window_imp->mCallbacks->handleQuit(window_imp); @@ -2482,6 +2488,50 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ } return 0; } + case WM_QUERYENDSESSION: + { + // Generally means that OS is going to shut down or user is going to log off. + // Can use ShutdownBlockReasonCreate here. + LL_INFOS("Window") << "Received WM_QUERYENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL; + return TRUE; // 1 = ok to end session. 0 no longer works by itself, use ShutdownBlockReasonCreate + } + case WM_ENDSESSION: + { + // OS session is shutting down, initiate cleanup. + // Comes after WM_QUERYENDSESSION + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ENDSESSION"); + LL_INFOS("Window") << "Received WM_ENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL; + unsigned int end_session_flags = (U32)w_param; + if (end_session_flags == 0) + { + // session is not actually ending + return 0; + } + + if ((end_session_flags & ENDSESSION_CLOSEAPP) + || (end_session_flags & ENDSESSION_CRITICAL) + || (end_session_flags & ENDSESSION_LOGOFF)) + { + window_imp->post([=]() + { + // Check if app needs cleanup or can be closed immediately. + if (window_imp->mCallbacks->handleSessionExit(window_imp)) + { + // Get the app to initiate cleanup. + window_imp->mCallbacks->handleQuit(window_imp); + // The app is responsible for calling destroyWindow when done with GL + } + }); + // Give app a second to finish up. That's not enough for a clean exit, + // but better than nothing. + // Todo: sync this better, some kind of waitForResult? Can't wait forever, + // but can potentially use ShutdownBlockReasonCreate for a bigger delay. + ms_sleep(1000); + } + // Don't need to post quit or destroy window, + // if session is ending OS is going to take care of it. + return 0; + } case WM_COMMAND: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_COMMAND"); @@ -3286,7 +3336,7 @@ bool LLWindowWin32::pasteTextFromClipboard(LLWString &dst) WCHAR *utf16str = (WCHAR*) GlobalLock(h_data); if (utf16str) { - dst = utf16str_to_wstring(utf16str); + dst = ll_convert(std::wstring(utf16str)); LLWStringUtil::removeWindowsCR(dst); GlobalUnlock(h_data); success = true; @@ -3311,8 +3361,8 @@ bool LLWindowWin32::copyTextToClipboard(const LLWString& wstr) // Provide a copy of the data in Unicode format. LLWString sanitized_string(wstr); LLWStringUtil::addCRLF(sanitized_string); - llutf16string out_utf16 = wstring_to_utf16str(sanitized_string); - const size_t size_utf16 = (out_utf16.length() + 1) * sizeof(WCHAR); + std::wstring out_utf16 = ll_convert(sanitized_string); + const size_t size_utf16 = (out_utf16.length() + 1) * sizeof(wchar_t); // Memory is allocated and then ownership of it is transfered to the system. HGLOBAL hglobal_copy_utf16 = GlobalAlloc(GMEM_MOVEABLE, size_utf16); @@ -3672,7 +3722,7 @@ void LLSplashScreenWin32::showImpl() ShowWindow(mWindow, SW_SHOW); // Should set taskbar text without creating a header for the window (caption) - SetWindowTextA(mWindow, "Second Life"); + SetWindowText(mWindow, TEXT("Second Life")); } @@ -3809,8 +3859,7 @@ void LLWindowWin32::spawnWebBrowser(const std::string& escaped_url, bool async) // reliablly on Vista. // this is madness.. no, this is.. - LLWString url_wstring = utf8str_to_wstring( escaped_url ); - llutf16string url_utf16 = wstring_to_utf16str( url_wstring ); + std::wstring url_utf16 = ll_convert(escaped_url); // let the OS decide what to use to open the URL SHELLEXECUTEINFO sei = { sizeof( sei ) }; @@ -4098,7 +4147,7 @@ void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont) U32 LLWindowWin32::fillReconvertString(const LLWString &text, S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string) { - const llutf16string text_utf16 = wstring_to_utf16str(text); + const std::wstring text_utf16 = ll_convert(text); const DWORD required_size = sizeof(RECONVERTSTRING) + (static_cast(text_utf16.length()) + 1) * sizeof(WCHAR); if (reconvert_string && reconvert_string->dwSize >= required_size) { @@ -4198,7 +4247,7 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes) size = LLWinImm::getCompositionString(himc, GCS_RESULTSTR, data, size); if (size > 0) { - result_string = utf16str_to_wstring(llutf16string(data, size / sizeof(WCHAR))); + result_string = ll_convert_wide_to_wstring(std::wstring(data, size / sizeof(WCHAR))); } delete[] data; needs_update = true; @@ -4215,7 +4264,7 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes) if (size > 0) { preedit_string_utf16_length = size / sizeof(WCHAR); - preedit_string = utf16str_to_wstring(llutf16string(data, size / sizeof(WCHAR))); + preedit_string = ll_convert_wide_to_wstring(std::wstring(data, size / sizeof(WCHAR))); } delete[] data; needs_update = true; diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index ec616cefbca..6bdc886319a 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -1282,7 +1282,7 @@ bool LLXMLNode::getAttributeU8(const char* name, U8& value ) bool LLXMLNode::getAttributeS8(const char* name, S8& value ) { LLXMLNodePtr node; - S32 val; + S32 val{}; if (!(getAttribute(name, node) && node->getIntValue(1, &val))) { return false; @@ -1294,7 +1294,7 @@ bool LLXMLNode::getAttributeS8(const char* name, S8& value ) bool LLXMLNode::getAttributeU16(const char* name, U16& value ) { LLXMLNodePtr node; - U32 val; + U32 val{}; if (!(getAttribute(name, node) && node->getUnsignedValue(1, &val))) { return false; @@ -1306,7 +1306,7 @@ bool LLXMLNode::getAttributeU16(const char* name, U16& value ) bool LLXMLNode::getAttributeS16(const char* name, S16& value ) { LLXMLNodePtr node; - S32 val; + S32 val{}; if (!(getAttribute(name, node) && node->getIntValue(1, &val))) { return false; diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index 64b6a4228d2..b6748abd476 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -12,13 +12,6 @@ include(PluginAPI) ### media_plugin_base -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) set(media_plugin_base_SOURCE_FILES media_plugin_base.cpp @@ -34,5 +27,5 @@ add_library(media_plugin_base ${media_plugin_base_SOURCE_FILES} ) -target_link_libraries( media_plugin_base llplugin ) +target_link_libraries( media_plugin_base llplugin ll::pluginlibraries) target_include_directories( media_plugin_base INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/indra/media_plugins/base/media_plugin_base.cpp b/indra/media_plugins/base/media_plugin_base.cpp index 545eee25a9b..ccaa43cfb50 100644 --- a/indra/media_plugins/base/media_plugin_base.cpp +++ b/indra/media_plugins/base/media_plugin_base.cpp @@ -170,10 +170,8 @@ void MediaPluginBase::sendStatus() #if LL_WINDOWS # define LLSYMEXPORT __declspec(dllexport) -#elif LL_LINUX -# define LLSYMEXPORT __attribute__ ((visibility("default"))) #else -# define LLSYMEXPORT /**/ +# define LLSYMEXPORT __attribute__ ((visibility("default"))) #endif extern "C" diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 0d1a8339366..dc2d82017d0 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -14,14 +14,6 @@ include(CEFPlugin) ### media_plugin_cef -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) - set(media_plugin_cef_SOURCE_FILES media_plugin_cef.cpp ) @@ -77,16 +69,8 @@ if (DARWIN) PROPERTIES PREFIX "" BUILD_WITH_INSTALL_RPATH 1 - INSTALL_NAME_DIR "@executable_path" + INSTALL_RPATH "@executable_path/../Frameworks" LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" ) - add_custom_command(TARGET media_plugin_cef - POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change "@executable_path/Chromium Embedded Framework" - "@executable_path/../../../../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" - "$" - VERBATIM - COMMENT "Fixing path to CEF Framework" - ) - endif (DARWIN) diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 64fc7e452b5..caf804f915d 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -38,6 +38,13 @@ #include "volume_catcher.h" #include "media_plugin_base.h" +// _getpid()/getpid() +#if LL_WINDOWS +#include +#else +#include +#endif + #include "dullahan.h" //////////////////////////////////////////////////////////////////////////////// @@ -64,7 +71,7 @@ class MediaPluginCEF : void onLoadStartCallback(); void onRequestExitCallback(); void onLoadEndCallback(int httpStatusCode, std::string url); - void onLoadError(int status, const std::string error_text); + void onLoadError(int status, const std::string error_text, const std::string error_url); void onAddressChangeCallback(std::string url); void onOpenPopupCallback(std::string url, std::string target); bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password); @@ -99,12 +106,14 @@ class MediaPluginCEF : std::string mAuthUsername; std::string mAuthPassword; bool mAuthOK; + bool mCanUndo; + bool mCanRedo; bool mCanCut; bool mCanCopy; bool mCanPaste; + bool mCanDelete; + bool mCanSelectAll; std::string mRootCachePath; - std::string mCachePath; - std::string mContextCachePath; std::string mCefLogFile; bool mCefLogVerbose; std::vector mPickedFiles; @@ -139,10 +148,13 @@ MediaPluginBase(host_send_func, host_user_data) mAuthUsername = ""; mAuthPassword = ""; mAuthOK = false; + mCanUndo = false; + mCanRedo = false; mCanCut = false; mCanCopy = false; mCanPaste = false; - mCachePath = ""; + mCanDelete = false; + mCanSelectAll = false; mCefLogFile = ""; mCefLogVerbose = false; mPickedFiles.clear(); @@ -242,15 +254,17 @@ void MediaPluginCEF::onLoadStartCallback() ///////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::onLoadError(int status, const std::string error_text) +void MediaPluginCEF::onLoadError(int status, const std::string error_text, const std::string error_url) { std::stringstream msg; - msg << "Loading error!"; + msg << "Loading error"; + msg << "

"; + msg << "Error message: " << error_text; msg << "

"; - msg << "Message: " << error_text; - msg << "
"; - msg << "Code: " << status; + msg << "Error URL: " << error_url << ""; + msg << "

"; + msg << "Error code: " << status; mCEFLib->showBrowserMessage(msg.str()); } @@ -607,7 +621,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string) mCEFLib->setOnTooltipCallback(std::bind(&MediaPluginCEF::onTooltipCallback, this, std::placeholders::_1)); mCEFLib->setOnLoadStartCallback(std::bind(&MediaPluginCEF::onLoadStartCallback, this)); mCEFLib->setOnLoadEndCallback(std::bind(&MediaPluginCEF::onLoadEndCallback, this, std::placeholders::_1, std::placeholders::_2)); - mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2)); + + // CEF 139 seems to have introduced a loading failure at the login page (only?) I haven't seen it on + // any other page and it only happens about 1 in 8 times. Without this handler for the error page + // (red box, error message/code/url) the page load recovers after display a brief built in error. + // Not ideal but better than stopping altgoether. Will restore this once I discover the error. + //mCEFLib->setOnLoadErrorCallback(std::bind(&MediaPluginCEF::onLoadError, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mCEFLib->setOnAddressChangeCallback(std::bind(&MediaPluginCEF::onAddressChangeCallback, this, std::placeholders::_1)); mCEFLib->setOnOpenPopupCallback(std::bind(&MediaPluginCEF::onOpenPopupCallback, this, std::placeholders::_1, std::placeholders::_2)); mCEFLib->setOnHTTPAuthCallback(std::bind(&MediaPluginCEF::onHTTPAuthCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); @@ -635,10 +654,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) // and set it to white settings.background_color = 0xffffffff; // white - settings.cache_enabled = true; settings.root_cache_path = mRootCachePath; - settings.cache_path = mCachePath; - settings.context_cache_path = mContextCachePath; settings.cookies_enabled = mCookiesEnabled; // configure proxy argument if enabled and valid @@ -729,23 +745,32 @@ void MediaPluginCEF::receiveMessage(const char* message_string) std::string user_data_path_cache = message_in.getValue("cache_path"); std::string subfolder = message_in.getValue("username"); - mRootCachePath = user_data_path_cache + "cef_cache"; - if (!subfolder.empty()) - { - std::string delim; + // media plugin doesn't have access to gDirUtilp + std::string path_separator; #if LL_WINDOWS - // media plugin doesn't have access to gDirUtilp - delim = "\\"; + path_separator = "\\"; #else - delim = "/"; + path_separator = "/"; #endif - mCachePath = mRootCachePath + delim + subfolder; - } - else - { - mCachePath = mRootCachePath; - } - mContextCachePath = ""; // disabled by "" + + mRootCachePath = user_data_path_cache + "cef_cache"; + + // Issue #4498 Introduce an additional sub-folder underneath the main cache + // folder so that each CEF media instance gets its own (as per the CEF API + // official position). These folders will be removed at startup by Viewer code + // so that their non-trivial size does not exhaust available disk space. This + // begs the question - why turn on the cache at all? There are 2 reasons - firstly + // some of the instances will benefit from per Viewer session caching and will + // use the injected SL cookie and secondly, it's not clear how having no cache + // interacts with the multiple simultaneous paradigm we use. + mRootCachePath += path_separator; +# if LL_WINDOWS + mRootCachePath += std::to_string(_getpid()); +# else + mRootCachePath += std::to_string(getpid()); +# endif + + mCefLogFile = message_in.getValue("cef_log_file"); mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log"); } @@ -923,6 +948,14 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { authResponse(message_in); } + if (message_name == "edit_undo") + { + mCEFLib->editUndo(); + } + if (message_name == "edit_redo") + { + mCEFLib->editRedo(); + } if (message_name == "edit_cut") { mCEFLib->editCut(); @@ -935,6 +968,18 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { mCEFLib->editPaste(); } + if (message_name == "edit_delete") + { + mCEFLib->editDelete(); + } + if (message_name == "edit_select_all") + { + mCEFLib->editSelectAll(); + } + if (message_name == "edit_show_source") + { + mCEFLib->viewSource(); + } } else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) { @@ -1086,14 +1131,31 @@ void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD // void MediaPluginCEF::checkEditState() { + bool can_undo = mCEFLib->editCanUndo(); + bool can_redo = mCEFLib->editCanRedo(); bool can_cut = mCEFLib->editCanCut(); bool can_copy = mCEFLib->editCanCopy(); bool can_paste = mCEFLib->editCanPaste(); + bool can_delete = mCEFLib->editCanDelete(); + bool can_select_all = mCEFLib->editCanSelectAll(); - if ((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste)) + if ((can_undo != mCanUndo) || (can_redo != mCanRedo) || (can_cut != mCanCut) || (can_copy != mCanCopy) + || (can_paste != mCanPaste) || (can_delete != mCanDelete) || (can_select_all != mCanSelectAll)) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state"); + if (can_undo != mCanUndo) + { + mCanUndo = can_undo; + message.setValueBoolean("undo", can_undo); + } + + if (can_redo != mCanRedo) + { + mCanRedo = can_redo; + message.setValueBoolean("redo", can_redo); + } + if (can_cut != mCanCut) { mCanCut = can_cut; @@ -1112,6 +1174,18 @@ void MediaPluginCEF::checkEditState() message.setValueBoolean("paste", can_paste); } + if (can_delete != mCanDelete) + { + mCanDelete = can_delete; + message.setValueBoolean("delete", can_delete); + } + + if (can_select_all != mCanSelectAll) + { + mCanSelectAll = can_select_all; + message.setValueBoolean("select_all", can_select_all); + } + sendMessage(message); } } diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index 41e2353f31c..be8ffe5a40a 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -13,14 +13,6 @@ include(ExamplePlugin) ### media_plugin_example -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) - set(media_plugin_example_SOURCE_FILES media_plugin_example.cpp ) @@ -47,7 +39,7 @@ if (DARWIN) PROPERTIES PREFIX "" BUILD_WITH_INSTALL_RPATH 1 - INSTALL_NAME_DIR "@executable_path" + INSTALL_RPATH "@executable_path/../Frameworks" LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" ) diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt index 202cbed96e6..d2b2a616487 100644 --- a/indra/media_plugins/libvlc/CMakeLists.txt +++ b/indra/media_plugins/libvlc/CMakeLists.txt @@ -13,13 +13,6 @@ include(LibVLCPlugin) ### media_plugin_libvlc -if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT ADDRESS_SIZE EQUAL 32) set(media_plugin_libvlc_SOURCE_FILES media_plugin_libvlc.cpp @@ -50,7 +43,7 @@ if (DARWIN) PROPERTIES PREFIX "" BUILD_WITH_INSTALL_RPATH 1 - INSTALL_NAME_DIR "@executable_path" + INSTALL_RPATH "@executable_path/../Frameworks" LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" ) diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 4240613a0c1..ad0ecaf4abf 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -174,7 +174,7 @@ void MediaPluginLibVLC::initVLC() }; #if LL_DARWIN - setenv("VLC_PLUGIN_PATH", ".", 1); + setenv("VLC_PLUGIN_PATH", "./plugins", 1); #endif int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5274986ff03..5a49b433678 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -291,6 +291,7 @@ set(viewer_SOURCE_FILES llfloatersceneloadstats.cpp llfloaterscriptdebug.cpp llfloaterscriptedprefs.cpp + llfloaterscripting.cpp llfloaterscriptlimits.cpp llfloatersearch.cpp llfloatersellland.cpp @@ -393,6 +394,7 @@ set(viewer_SOURCE_FILES llmaniprotate.cpp llmanipscale.cpp llmaniptranslate.cpp + llfloatermarketplace.cpp llmarketplacefunctions.cpp llmarketplacenotifications.cpp llmaterialeditor.cpp @@ -550,6 +552,7 @@ set(viewer_SOURCE_FILES llsceneview.cpp llscreenchannel.cpp llscripteditor.cpp + llscripteditorws.cpp llscriptfloater.cpp llscrollingpanelparam.cpp llscrollingpanelparambase.cpp @@ -930,6 +933,7 @@ set(viewer_HEADER_FILES llfloaterlinkreplace.h llfloaterloadprefpreset.h llfloatermap.h + llfloatermarketplace.h llfloatermarketplacelistings.h llfloatermediasettings.h llfloatermemleak.h @@ -968,6 +972,7 @@ set(viewer_HEADER_FILES llfloatersceneloadstats.h llfloaterscriptdebug.h llfloaterscriptedprefs.h + llfloaterscripting.h llfloaterscriptlimits.h llfloatersearch.h llfloatersellland.h @@ -1214,6 +1219,7 @@ set(viewer_HEADER_FILES llsceneview.h llscreenchannel.h llscripteditor.h + llscripteditorws.h llscriptfloater.h llscriptruntimeperms.h llscrollingpanelparam.h @@ -1420,7 +1426,7 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}\n") set_source_files_properties( - llversioninfo.cpp tests/llversioninfo_test.cpp + llversioninfo.cpp tests/llversioninfo_test.cpp PROPERTIES COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake ) @@ -1464,7 +1470,7 @@ if (DARWIN) set(viewer_RESOURCE_FILES secondlife.icns Info-SecondLife.plist - SecondLife.xib/ + SecondLife.xib # CMake doesn't seem to support Xcode language variants well just yet English.lproj/InfoPlist.strings English.lproj/language.txt @@ -1635,7 +1641,7 @@ endif (WINDOWS) file(GLOB_RECURSE viewer_XUI_FILES LIST_DIRECTORIES FALSE ${CMAKE_CURRENT_SOURCE_DIR}/skins/*.xml) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/skins PREFIX "XUI Files" FILES ${viewer_XUI_FILES}) -set_source_files_properties(${viewer_XUI_FILES} +set_source_files_properties(${viewer_XUI_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) list(APPEND viewer_SOURCE_FILES ${viewer_XUI_FILES}) @@ -1643,11 +1649,12 @@ list(APPEND viewer_SOURCE_FILES ${viewer_XUI_FILES}) file(GLOB_RECURSE viewer_SHADER_FILES LIST_DIRECTORIES FALSE ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/shaders/*.glsl) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/shaders PREFIX "Shaders" FILES ${viewer_SHADER_FILES}) -set_source_files_properties(${viewer_SHADER_FILES} +set_source_files_properties(${viewer_SHADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) list(APPEND viewer_SOURCE_FILES ${viewer_SHADER_FILES}) - +# note that the scripts which publish these files are sensitive to the file +# extensions. Be cautious about adding new file types here. set(viewer_APPSETTINGS_FILES app_settings/anim.ini app_settings/autoreplace.xml @@ -1659,6 +1666,7 @@ set(viewer_APPSETTINGS_FILES app_settings/ignorable_dialogs.xml app_settings/key_bindings.xml app_settings/keywords_lsl_default.xml + app_settings/keywords_lua_default.xml app_settings/logcontrol.xml app_settings/settings.xml app_settings/settings_crash_behavior.xml @@ -1667,8 +1675,9 @@ set(viewer_APPSETTINGS_FILES app_settings/std_bump.ini app_settings/toolbars.xml app_settings/trees.xml + app_settings/types_lua_default.xml app_settings/viewerart.xml - ${CMAKE_SOURCE_DIR}/../etc/message.xml + app_settings/message.xml ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg packages-info.txt featuretable.txt @@ -1761,8 +1770,8 @@ if (WINDOWS) # And of course it's straightforward to read a text file in Python. set(COPY_INPUT_DEPENDENCIES - # The following commented dependencies are determined at variably at build time. Can't do this here. - ${CMAKE_SOURCE_DIR}/../etc/message.xml + # The following commented dependencies are determined variably at build time. Can't do this here. + app_settings/message.xml ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg ${SHARED_LIB_STAGING_DIR}/openjp2.dll ${SHARED_LIB_STAGING_DIR}/llwebrtc.dll @@ -1947,7 +1956,9 @@ if (WINDOWS) elseif (DARWIN) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES - LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP" + RESOURCE SecondLife.xib + #LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip -Xlinker -map -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}.MAP" + LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Xlinker -dead_strip" ) else (WINDOWS) # Linux @@ -1970,7 +1981,7 @@ endif (WINDOWS) # one of these being libz where you can find four or more versions in play # at once. On Linux, libz can be found at link and run time via a number # of paths: -# +# # => -lfreetype # => libz.so.1 (on install machine, not build) # => -lSDL @@ -2003,12 +2014,12 @@ target_link_libraries(${VIEWER_BINARY_NAME} llcommon llmeshoptimizer llwebrtc - ll::ndof lllogin llprimitive llappearance ${LLPHYSICSEXTENSIONS_LIBRARIES} ll::bugsplat + ll::ndof ll::tracy ll::openxr ) @@ -2046,7 +2057,7 @@ foreach(elem ${country_codes}) set(emoji_mapping_src_file "${emoji_mapping_src_folder}/${elem}/emoji_characters.xml") set(emoji_mapping_dst_file - "${emoji_mapping_dst_folder}/${elem}/emoji_characters.xml") + "${emoji_mapping_dst_folder}/${elem}/emoji_characters.xml") configure_file(${emoji_mapping_src_file} ${emoji_mapping_dst_file} COPYONLY) endforeach() @@ -2148,16 +2159,14 @@ if (DARWIN) # https://blog.kitware.com/upcoming-in-cmake-2-8-12-osx-rpath-support/ set(CMAKE_MACOSX_RPATH 1) - + set_target_properties( ${VIEWER_BINARY_NAME} PROPERTIES OUTPUT_NAME "${product}" # From Contents/MacOS/SecondLife, look in Contents/Frameworks - INSTALL_RPATH "@loader_path/../Frameworks" - # SIGH, as of 2018-05-24 (cmake 3.11.1) the INSTALL_RPATH property simply - # does not work. Try this: - LINK_FLAGS "-rpath @loader_path/../Frameworks" + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_RPATH "@executable_path/../Frameworks" MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist" XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${MACOSX_BUNDLE_GUI_IDENTIFIER}" ) @@ -2191,9 +2200,6 @@ if (DARWIN) --grid=${GRID} --source=${CMAKE_CURRENT_SOURCE_DIR} --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt - DEPENDS - ${VIEWER_BINARY_NAME} - ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef) @@ -2228,8 +2234,6 @@ if (DARWIN) --touch=${CMAKE_CURRENT_BINARY_DIR}/$,$,>/.${product}.bat --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt ${SIGNING_SETTING} - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) endif (PACKAGE) endif (DARWIN) @@ -2269,7 +2273,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE PROPERTIES XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym" XCODE_ATTRIBUTE_DWARF_DSYM_FOLDER_PATH "${SYMBOLS_STAGING_DIR}/dSYMs") - + add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}" COMMAND "zip" ARGS @@ -2304,7 +2308,7 @@ if (LL_TESTS) # llremoteparcelrequest.cpp llviewerhelputil.cpp llversioninfo.cpp -# llvocache.cpp +# llvocache.cpp llworldmap.cpp llworldmipmap.cpp ) @@ -2313,7 +2317,7 @@ if (LL_TESTS) llworldmap.cpp llworldmipmap.cpp PROPERTIES - LL_TEST_ADDITIONAL_SOURCE_FILES + LL_TEST_ADDITIONAL_SOURCE_FILES tests/llviewertexture_stub.cpp #llviewertexturelist.cpp ) @@ -2347,7 +2351,7 @@ if (LL_TESTS) llworldmap.cpp llworldmipmap.cpp PROPERTIES - LL_TEST_ADDITIONAL_SOURCE_FILES + LL_TEST_ADDITIONAL_SOURCE_FILES tests/llviewertexture_stub.cpp ) diff --git a/indra/newview/SecondLife.nib b/indra/newview/SecondLife.nib deleted file mode 100644 index c4ddca50dc1..00000000000 Binary files a/indra/newview/SecondLife.nib and /dev/null differ diff --git a/indra/newview/SecondLife.xib b/indra/newview/SecondLife.xib index fbff8fe3073..781a3906731 100644 --- a/indra/newview/SecondLife.xib +++ b/indra/newview/SecondLife.xib @@ -1,1136 +1,193 @@ - - - 1060 - 12E55 - 4457.6 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 4457.6 - - - NSCustomObject - NSMenu - NSMenuItem - NSScrollView - NSScroller - NSTextView - NSView - NSWindowTemplate - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - NSApplication - - - FirstResponder - - - NSApplication - - - Main Menu - - - - Second Life - - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - Second Life - - - - About Second Life - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Services - - 2147483647 - - - submenuAction: - - Services - - _NSServicesMenu - - - - - YES - YES - - - 2147483647 - - - - - - Hide Second Life - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Quit Second Life - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - Edit - - 2147483647 - - - submenuAction: - - Edit - - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - - - - Window - - 2147483647 - - - submenuAction: - - Window - - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 2147483647 - - - - - - Enter Full Screen - f - 1310720 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bring All to Front - - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - - - _NSMainMenu - - - LLAppDelegate - - - 15 - 2 - {{196, 240}, {1024, 600}} - 74974208 - Second Life - LLNSWindow - - - - - 256 - - {1024, 600} - - - _NS:20 - - {{0, 0}, {2560, 1418}} - {10000000000000, 10000000000000} - Second Life - 128 - NO - - - 31 - 2 - {{272, 176}, {938, 42}} - -1535638528 - Input Window - LLUserInputWindow - - - - - 256 - - - - 256 - - - - 2322 - - - - 2322 - - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - Apple URL pasteboard type - CorePasteboardFlavorType 0x6D6F6F76 - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - NeXT font pasteboard type - NeXT ruler pasteboard type - WebURLsWithTitlesPboardType - public.url - - {938, 42} - - - - _NS:13 - - - - - - - - - - - - 166 - - - - 938 - 1 - - - 67121127 - 0 - - - 3 - MQA - - - - 6 - System - selectedTextBackgroundColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - selectedTextColor - - 3 - MAA - - - - - - - 1 - MCAwIDEAA - - - {8, -8} - 13 - - - - - - 1 - - 6 - {939, 10000000} - - - - {{1, 1}, {938, 42}} - - - - _NS:11 - - - - {4, 5} - - 79691776 - - - - - - file://localhost/Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework/Resources/DVTIbeamCursor.tiff - - - - - 3 - MCAwAA - - - - 4 - - - - 256 - {{923, 1}, {16, 42}} - - - - _NS:83 - NO - - _doScroller: - 0.96666666666666667 - - - - -2147483392 - {{-100, -100}, {87, 18}} - - - - _NS:33 - NO - 1 - - _doScroller: - 1 - 0.94565218687057495 - - - {{-1, -1}, {940, 44}} - - - - _NS:9 - 133138 - - - - 0.25 - 4 - 1 - - - {938, 42} - - - - _NS:21 - - {{0, 0}, {2560, 1418}} - {10000000000000, 10000000000000} - YES - - - - - - - terminate: - - - - 823 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - delegate - - - - 845 - - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - performZoom: - - - - 240 - - - - hide: - - - - 369 - - - - hideOtherApplications: - - - - 370 - - - - unhideAllApplications: - - - - 372 - - - - cut: - - - - 768 - - - - paste: - - - - 769 - - - - undo: - - - - 776 - - - - copy: - - - - 782 - - - - selectAll: - - - - 785 - - - - toggleFullScreen: - - - - 842 - - - - window - - - - 850 - - - - inputWindow - - - - 953 - - - - inputView - - - - 954 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - - - - - - - Main Menu - - - 19 - - - - - - - - 56 - - - - - - - - 103 - - - - - - 57 - - - - - - - - - - - - - - - - - - 58 - - - - - 134 - - - - - 150 - - - - - 136 - - - - - 144 - - - - - 129 - - - - - 143 - - - - - 236 - - - - - 131 - - - - - - - - 149 - - - - - 145 - - - - - 130 - - - - - 24 - - - - - - - - - - - - 92 - - - - - 5 - - - - - 239 - - - - - 23 - - - - - 711 - - - - - - - - 712 - - - - - - - - - - - - - - 716 - - - - - 717 - - - - - 718 - - - - - 721 - - - - - 824 - - - - - 841 - - - - - 828 - - - - - - - - 829 - - - - - - 713 - - - - - 714 - - - - - 715 - - - - - 941 - - - - - - - - 942 - - - - - - - - 943 - - - - - - - - - - 944 - - - - - 945 - - - - - 946 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - LLNonInlineTextView - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 954 - - - - - LLAppDelegate - NSObject - - LLNonInlineTextView - NSWindow - LLNSWindow - - - - inputView - LLNonInlineTextView - - - inputWindow - NSWindow - - - window - LLNSWindow - - - - IBProjectSource - ./Classes/LLAppDelegate.h - - - - LLNSWindow - NSWindow - - IBProjectSource - ./Classes/LLNSWindow.h - - - - LLNonInlineTextView - NSTextView - - IBProjectSource - ./Classes/LLNonInlineTextView.h - - - - LLUserInputWindow - NSPanel - - IBProjectSource - ./Classes/LLUserInputWindow.h - - - - NSTextView - - id - id - - - - orderFrontSharingServicePicker: - id - - - toggleQuickLookPreviewPanel: - id - - - - IBProjectSource - ./Classes/NSTextView.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/app_settings/keywords_lsl_default.xml b/indra/newview/app_settings/keywords_lsl_default.xml index f99b86bd399..db9bc9924ff 100644 --- a/indra/newview/app_settings/keywords_lsl_default.xml +++ b/indra/newview/app_settings/keywords_lsl_default.xml @@ -1,4 +1,3 @@ - controls @@ -31,7 +30,7 @@ return tooltip - Leave current event or function.\nreturn [<variable>];\nOptionally pass back a variable's value, from a function. + Leave current event or function.\nreturn [<variable>];\nOptionally pass back a variable's value, from a function. state @@ -59,12 +58,12 @@ key tooltip - A 128 bit unique identifier (UUID).\nThe key is represented as hexidecimal characters (A-F and 0-9), grouped into sections (8,4,4,4,12 characters) and separated by hyphens (for a total of 36 characters). e.g. "A822FF2B-FF02-461D-B45D-DCD10A2DE0C2". + A 128 bit unique identifier (UUID).\nThe key is represented as hexidecimal characters (A-F and 0-9), grouped into sections (8,4,4,4,12 characters) and separated by hyphens (for a total of 36 characters). e.g. "A822FF2B-FF02-461D-B45D-DCD10A2DE0C2". list tooltip - A collection of other data types.\nLists are signified by square brackets surrounding their elements; the elements inside are separated by commas. e.g. [0, 1, 2, 3, 4] or ["Yes", "No", "Perhaps"]. + A collection of other data types.\nLists are signified by square brackets surrounding their elements; the elements inside are separated by commas. e.g. [0, 1, 2, 3, 4] or ["Yes", "No", "Perhaps"]. quaternion @@ -74,7 +73,7 @@ rotation tooltip - The rotation type is one of several ways to represent an orientation in 3D.\nIt is a mathematical object called a quaternion. You can think of a quaternion as four numbers (x, y, z, w), three of which represent the direction an object is facing and a fourth that represents the object's banking left or right around that direction. + The rotation type is one of several ways to represent an orientation in 3D.\nIt is a mathematical object called a quaternion. You can think of a quaternion as four numbers (x, y, z, w), three of which represent the direction an object is facing and a fourth that represents the object's banking left or right around that direction. string @@ -91,14750 +90,19403 @@ ACTIVE + tooltip + Objects in world that are running a script or currently physically moving. type integer value 0x2 - tooltip - Objects in world that are running a script or currently physically moving. AGENT + tooltip + Objects in world that are agents. type integer value 0x1 - tooltip - Objects in world that are agents. AGENT_ALWAYS_RUN + tooltip + type integer value 0x1000 - tooltip - AGENT_ATTACHMENTS + tooltip + The agent has attachments. type integer value 0x2 + + AGENT_AUTOMATED + tooltip - The agent has attachments. + The agent has been identified as a scripted agent + type + integer + value + 0x4000 AGENT_AUTOPILOT + tooltip + type integer value 0x2000 - tooltip - AGENT_AWAY + tooltip + type integer value 0x40 - tooltip - AGENT_BUSY + tooltip + type integer value 0x800 - tooltip - AGENT_BY_LEGACY_NAME + tooltip + type integer value 0x1 - tooltip - AGENT_BY_USERNAME + tooltip + type integer value 0x10 - tooltip - AGENT_CROUCHING + tooltip + type integer value 0x400 + + AGENT_FLOATING_VIA_SCRIPTED_ATTACHMENT + tooltip - + The agent is floating via scripted attachment. + type + integer + value + 0x8000 AGENT_FLYING + tooltip + The agent is flying. type integer value 0x1 - tooltip - The agent is flying. AGENT_IN_AIR + tooltip + type integer value 0x100 - tooltip - AGENT_LIST_PARCEL + tooltip + Agents on the same parcel where the script is running. type integer value - 1 - tooltip - Agents on the same parcel where the script is running. + 1 AGENT_LIST_PARCEL_OWNER + tooltip + Agents on any parcel in the region where the parcel owner is the same as the owner of the parcel under the scripted object. type integer value - 2 - tooltip - Agents on any parcel in the region where the parcel owner is the same as the owner of the parcel under the scripted object. + 2 AGENT_LIST_REGION + tooltip + All agents in the region. type integer value - 4 - tooltip - All agents in the region. + 4 AGENT_MOUSELOOK + tooltip + type integer value 0x8 - tooltip - AGENT_ON_OBJECT + tooltip + type integer value 0x20 - tooltip - AGENT_SCRIPTED + tooltip + The agent has scripted attachments. type integer value 0x4 - tooltip - The agent has scripted attachments. AGENT_SITTING + tooltip + type integer value 0x10 - tooltip - AGENT_TYPING + tooltip + type integer value 0x200 - tooltip - AGENT_WALKING + tooltip + type integer value 0x80 - tooltip - ALL_SIDES + tooltip + type integer value - -1 - tooltip - + -1 ANIM_ON + tooltip + Texture animation is on. type integer value 0x1 + + ATTACH_ANY_HUD + tooltip - Texture animation is on. + Filtering for any HUD attachment. + type + integer + value + -1 ATTACH_AVATAR_CENTER + tooltip + Attach to the avatar's geometric centre. type integer value - 40 - tooltip - Attach to the avatar's geometric centre. + 40 ATTACH_BACK + tooltip + Attach to the avatar's back. type integer value - 9 - tooltip - Attach to the avatar's back. + 9 ATTACH_BELLY + tooltip + Attach to the avatar's belly. type integer value - 28 - tooltip - Attach to the avatar's belly. + 28 ATTACH_CHEST + tooltip + Attach to the avatar's chest. type integer value - 1 - tooltip - Attach to the avatar's chest. + 1 ATTACH_CHIN + tooltip + Attach to the avatar's chin. + type + integer + value + 12 + + ATTACH_FACE_JAW + + tooltip + Attach to the avatar's jaw. + type + integer + value + 47 + + ATTACH_FACE_LEAR + + tooltip + Attach to the avatar's left ear (extended). + type + integer + value + 48 + + ATTACH_FACE_LEYE + + tooltip + Attach to the avatar's left eye (extended). + type + integer + value + 50 + + ATTACH_FACE_REAR + + tooltip + Attach to the avatar's right ear (extended). + type + integer + value + 49 + + ATTACH_FACE_REYE + + tooltip + Attach to the avatar's right eye (extended). + type + integer + value + 51 + + ATTACH_FACE_TONGUE + + tooltip + Attach to the avatar's tongue. type integer value - 12 + 52 + + ATTACH_GROIN + tooltip - Attach to the avatar's chin. + Attach to the avatar's groin. + type + integer + value + 53 ATTACH_HEAD + tooltip + Attach to the avatar's head. + type + integer + value + 2 + + ATTACH_HIND_LFOOT + + tooltip + Attach to the avatar's left hind foot. type integer value - 2 + 54 + + ATTACH_HIND_RFOOT + tooltip - Attach to the avatar's head. + Attach to the avatar's right hind foot. + type + integer + value + 55 ATTACH_HUD_BOTTOM + tooltip + type integer value - 37 - tooltip - + 37 ATTACH_HUD_BOTTOM_LEFT + tooltip + type integer value - 36 - tooltip - + 36 ATTACH_HUD_BOTTOM_RIGHT + tooltip + type integer value - 38 - tooltip - + 38 ATTACH_HUD_CENTER_1 + tooltip + type integer value - 35 - tooltip - + 35 ATTACH_HUD_CENTER_2 + tooltip + type integer value - 31 - tooltip - + 31 ATTACH_HUD_TOP_CENTER + tooltip + type integer value - 33 - tooltip - + 33 ATTACH_HUD_TOP_LEFT + tooltip + type integer value - 34 - tooltip - + 34 ATTACH_HUD_TOP_RIGHT + tooltip + type integer value - 32 - tooltip - + 32 ATTACH_LEAR + tooltip + Attach to the avatar's left ear. type integer value - 13 - tooltip - Attach to the avatar's left ear. + 13 ATTACH_LEFT_PEC + tooltip + Attach to the avatar's left pectoral. type integer value - 29 - tooltip - Attach to the avatar's left pectoral. + 29 ATTACH_LEYE + tooltip + Attach to the avatar's left eye. type integer value - 15 - tooltip - Attach to the avatar's left eye. + 15 ATTACH_LFOOT + tooltip + Attach to the avatar's left foot. type integer value - 7 - tooltip - Attach to the avatar's left foot. + 7 ATTACH_LHAND + tooltip + Attach to the avatar's left hand. type integer value - 5 + 5 + + ATTACH_LHAND_RING1 + tooltip - Attach to the avatar's left hand. + Attach to the avatar's left ring finger. + type + integer + value + 41 ATTACH_LHIP + tooltip + Attach to the avatar's left hip. type integer value - 25 - tooltip - Attach to the avatar's left hip. + 25 ATTACH_LLARM + tooltip + Attach to the avatar's left lower arm. type integer value - 21 - tooltip - Attach to the avatar's left lower arm. + 21 ATTACH_LLLEG + tooltip + Attach to the avatar's lower left leg. type integer value - 27 - tooltip - Attach to the avatar's lower left leg. + 27 ATTACH_LPEC deprecated - true + 1 + tooltip + Attach to the avatar's right pectoral. (Deprecated, use ATTACH_RIGHT_PEC) type integer value - 30 - tooltip - Attach to the avatar's right pectoral. (Deprecated, use ATTACH_RIGHT_PEC) + 30 ATTACH_LSHOULDER + tooltip + Attach to the avatar's left shoulder. type integer value - 3 - tooltip - Attach to the avatar's left shoulder. + 3 ATTACH_LUARM + tooltip + Attach to the avatar's left upper arm. type integer value - 20 - tooltip - Attach to the avatar's left upper arm. + 20 ATTACH_LULEG + tooltip + Attach to the avatar's lower upper leg. type integer value - 26 + 26 + + ATTACH_LWING + tooltip - Attach to the avatar's lower upper leg. + Attach to the avatar's left wing. + type + integer + value + 45 ATTACH_MOUTH + tooltip + Attach to the avatar's mouth. type integer value - 11 - tooltip - Attach to the avatar's mouth. + 11 ATTACH_NECK + tooltip + Attach to the avatar's neck. type integer value - 39 - tooltip - Attach to the avatar's neck. + 39 ATTACH_NOSE + tooltip + Attach to the avatar's nose. type integer value - 17 - tooltip - Attach to the avatar's nose. + 17 ATTACH_PELVIS + tooltip + Attach to the avatar's pelvis. type integer value - 10 - tooltip - Attach to the avatar's pelvis. + 10 ATTACH_REAR + tooltip + Attach to the avatar's right ear. type integer value - 14 - tooltip - Attach to the avatar's right ear. + 14 ATTACH_REYE + tooltip + Attach to the avatar's right eye. type integer value - 16 - tooltip - Attach to the avatar's right eye. + 16 ATTACH_RFOOT + tooltip + Attach to the avatar's right foot. type integer value - 8 - tooltip - Attach to the avatar's right foot. + 8 ATTACH_RHAND + tooltip + Attach to the avatar's right hand. type integer value - 6 + 6 + + ATTACH_RHAND_RING1 + tooltip - Attach to the avatar's right hand. + Attach to the avatar's right ring finger. + type + integer + value + 42 ATTACH_RHIP + tooltip + Attach to the avatar's right hip. type integer value - 22 - tooltip - Attach to the avatar's right hip. + 22 ATTACH_RIGHT_PEC + tooltip + Attach to the avatar's right pectoral. type integer value - 30 - tooltip - Attach to the avatar's right pectoral. + 30 ATTACH_RLARM + tooltip + Attach to the avatar's right lower arm. type integer value - 19 - tooltip - Attach to the avatar's right lower arm. + 19 ATTACH_RLLEG + tooltip + Attach to the avatar's right lower leg. type integer value - 24 - tooltip - Attach to the avatar's right lower leg. + 24 ATTACH_RPEC deprecated - true + 1 + tooltip + Attach to the avatar's left pectoral. (deprecated, use ATTACH_LEFT_PEC) type integer value - 29 - tooltip - Attach to the avatar's left pectoral. (deprecated, use ATTACH_LEFT_PEC) + 29 ATTACH_RSHOULDER + tooltip + Attach to the avatar's right shoulder. type integer value - 4 - tooltip - Attach to the avatar's right shoulder. + 4 ATTACH_RUARM + tooltip + Attach to the avatar's right upper arm. type integer value - 18 - tooltip - Attach to the avatar's right upper arm. + 18 ATTACH_RULEG - type - integer - value - 23 tooltip - Attach to the avatar's right upper leg. - - ATTACH_LHAND_RING1 - + Attach to the avatar's right upper leg. type integer value - 41 - tooltip - Attach to the avatar's left ring finger. + 23 - ATTACH_RHAND_RING1 + ATTACH_RWING + tooltip + Attach to the avatar's right wing. type integer value - 42 - tooltip - Attach to the avatar's right ring finger. + 46 ATTACH_TAIL_BASE + tooltip + Attach to the avatar's tail base. type integer value - 43 - tooltip - Attach to the avatar's tail base. + 43 ATTACH_TAIL_TIP + tooltip + Attach to the avatar's tail tip. type integer value - 44 - tooltip - Attach to the avatar's tail tip. + 44 - ATTACH_LWING + AVOID_CHARACTERS + tooltip + type integer value - 45 - tooltip - Attach to the avatar's left wing. - - ATTACH_RWING - - type - integer - value - 46 - tooltip - Attach to the avatar's right wing. - - ATTACH_FACE_JAW - - type - integer - value - 47 - tooltip - Attach to the avatar's jaw. - - ATTACH_FACE_LEAR - - type - integer - value - 48 - tooltip - Attach to the avatar's left ear (extended). - - ATTACH_FACE_REAR - - type - integer - value - 49 - tooltip - Attach to the avatar's right ear (extended). - - ATTACH_FACE_LEYE - - type - integer - value - 50 - tooltip - Attach to the avatar's left eye (extended). - - ATTACH_FACE_REYE - - type - integer - value - 51 - tooltip - Attach to the avatar's right eye (extended). - - ATTACH_FACE_TONGUE - - type - integer - value - 52 - tooltip - Attach to the avatar's tongue. + 1 - ATTACH_GROIN + AVOID_DYNAMIC_OBSTACLES - type - integer - value - 53 tooltip - Attach to the avatar's groin. - - ATTACH_HIND_LFOOT - + type integer value - 54 - tooltip - Attach to the avatar's left hind foot. + 2 - ATTACH_HIND_RFOOT + AVOID_NONE - type - integer - value - 55 tooltip - Attach to the avatar's right hind foot. - - AVOID_CHARACTERS - + type integer value - 1 - tooltip - + 0 - AVOID_DYNAMIC_OBSTACLES + BEACON_MAP - type - integer - value - 2 tooltip - - - AVOID_NONE - + Cause llMapBeacon to optionally display and focus the world map on the avatar's viewer. type integer value - 0 - tooltip - + 1 CAMERA_ACTIVE + tooltip + type integer value - 12 - tooltip - + 12 CAMERA_BEHINDNESS_ANGLE + tooltip + type integer value - 8 - tooltip - + 8 CAMERA_BEHINDNESS_LAG + tooltip + type integer value - 9 - tooltip - + 9 CAMERA_DISTANCE + tooltip + type integer value - 7 - tooltip - + 7 CAMERA_FOCUS + tooltip + type integer value - 17 - tooltip - + 17 CAMERA_FOCUS_LAG + tooltip + type integer value - 6 - tooltip - + 6 CAMERA_FOCUS_LOCKED + tooltip + type integer value - 22 - tooltip - + 22 CAMERA_FOCUS_OFFSET + tooltip + type integer value - 1 - tooltip - + 1 CAMERA_FOCUS_THRESHOLD + tooltip + type integer value - 11 - tooltip - + 11 CAMERA_PITCH + tooltip + type integer value - 0 - tooltip - + 0 CAMERA_POSITION + tooltip + type integer value - 13 - tooltip - + 13 CAMERA_POSITION_LAG + tooltip + type integer value - 5 - tooltip - + 5 CAMERA_POSITION_LOCKED + tooltip + type integer value - 21 - tooltip - + 21 CAMERA_POSITION_THRESHOLD + tooltip + type integer value - 10 - tooltip - + 10 CHANGED_ALLOWED_DROP + tooltip + The object inventory has changed because an item was added through the llAllowInventoryDrop interface. type integer value 0x40 - tooltip - The object inventory has changed because an item was added through the llAllowInventoryDrop interface. CHANGED_COLOR + tooltip + The object color has changed. type integer value 0x2 - tooltip - The object color has changed. CHANGED_INVENTORY + tooltip + The object inventory has changed. type integer value 0x1 - tooltip - The object inventory has changed. CHANGED_LINK + tooltip + The object has linked or its links were broken. type integer value 0x20 - tooltip - The object has linked or its links were broken. CHANGED_MEDIA + tooltip + type integer value 0x800 - tooltip - CHANGED_OWNER + tooltip + type integer value 0x80 - tooltip - CHANGED_REGION + tooltip + type integer value 0x100 - tooltip - CHANGED_REGION_START + tooltip + type integer value 0x400 + + CHANGED_RENDER_MATERIAL + tooltip - + The render material has changed. + type + integer + value + 0x1000 CHANGED_SCALE + tooltip + The object scale (size) has changed. type integer value 0x8 - tooltip - The object scale (size) has changed. CHANGED_SHAPE + tooltip + The object base shape has changed, e.g., a box to a cylinder. type integer value 0x4 - tooltip - The object base shape has changed, e.g., a box to a cylinder. CHANGED_TELEPORT + tooltip + type integer value 0x200 - tooltip - CHANGED_TEXTURE + tooltip + The texture offset, scale rotation, or simply the object texture has changed. type integer value 0x10 - tooltip - The texture offset, scale rotation, or simply the object texture has changed. CHARACTER_ACCOUNT_FOR_SKIPPED_FRAMES + tooltip + If set to false, character will not attempt to catch up on lost time when pathfinding performance is low, potentially providing more reliable movement (albeit while potentially appearing to be more stuttery). Default is true to match pre-existing behavior. type integer value - 14 - tooltip - If set to false, character will not attempt to catch up on lost time when pathfinding performance is low, potentially providing more reliable movement (albeit while potentially appearing to be more stuttery). Default is true to match pre-existing behavior. + 14 CHARACTER_AVOIDANCE_MODE + tooltip + Allows you to specify that a character should not try to avoid other characters, should not try to avoid dynamic obstacles (relatively fast moving objects and avatars), or both. type integer value - 5 - tooltip - Allows you to specify that a character should not try to avoid other characters, should not try to avoid dynamic obstacles (relatively fast moving objects and avatars), or both. + 5 CHARACTER_CMD_JUMP + tooltip + Makes the character jump. Requires an additional parameter, the height to jump, between 0.1m and 2.0m. This must be provided as the first element of the llExecCharacterCmd option list. type integer value 0x01 - tooltip - Makes the character jump. Requires an additional parameter, the height to jump, between 0.1m and 2.0m. This must be provided as the first element of the llExecCharacterCmd option list. CHARACTER_CMD_SMOOTH_STOP + tooltip + type integer value - 2 - tooltip - + 2 CHARACTER_CMD_STOP + tooltip + Stops any current pathfinding operation. type integer value 0x00 - tooltip - Stops any current pathfinding operation. CHARACTER_DESIRED_SPEED + tooltip + Speed of pursuit in meters per second. type integer value - 1 - tooltip - Speed of pursuit in meters per second. + 1 CHARACTER_DESIRED_TURN_SPEED + tooltip + The character's maximum speed while turning about the Z axis. - Note that this is only loosely enforced. type integer value - 12 - tooltip - The character's maximum speed while turning about the Z axis. - Note that this is only loosely enforced. + 12 CHARACTER_LENGTH + tooltip + Set collision capsule length - cannot be less than two times the radius. type integer value - 3 - tooltip - Set collision capsule length - cannot be less than two times the radius. + 3 CHARACTER_MAX_ACCEL + tooltip + The character's maximum acceleration rate. type integer value - 8 - tooltip - The character's maximum acceleration rate. + 8 CHARACTER_MAX_DECEL + tooltip + The character's maximum deceleration rate. type integer value - 9 - tooltip - The character's maximum deceleration rate. + 9 CHARACTER_MAX_SPEED + tooltip + The character's maximum speed. type integer value - 13 - tooltip - The character's maximum speed. + 13 CHARACTER_MAX_TURN_RADIUS + tooltip + The character's turn radius when travelling at CHARACTER_MAX_TURN_SPEED. type integer value - 10 - tooltip - The character's turn radius when travelling at CHARACTER_MAX_TURN_SPEED. + 10 CHARACTER_ORIENTATION + tooltip + Valid options are: VERTICAL, HORIZONTAL. type integer value - 4 - tooltip - Valid options are: VERTICAL, HORIZONTAL. + 4 CHARACTER_RADIUS + tooltip + Set collision capsule radius. type integer value - 2 - tooltip - Set collision capsule radius. + 2 CHARACTER_STAY_WITHIN_PARCEL + tooltip + Determines whether a character can leave its starting parcel.\nTakes a boolean parameter. If TRUE, the character cannot voluntarilly leave the parcel, but can return to it. type integer value - 15 - tooltip - Determines whether a character can leave its starting parcel.\nTakes a boolean parameter. If TRUE, the character cannot voluntarilly leave the parcel, but can return to it. + 15 CHARACTER_TYPE + tooltip + Specifies which walk-ability coefficient will be used by this character. type integer value - 6 - tooltip - Specifies which walk-ability coefficient will be used by this character. + 6 CHARACTER_TYPE_A + tooltip + type integer value - 0 - tooltip - + 0 CHARACTER_TYPE_B + tooltip + type integer value - 1 - tooltip - + 1 CHARACTER_TYPE_C + tooltip + type integer value - 2 - tooltip - + 2 CHARACTER_TYPE_D + tooltip + type integer value - 3 - tooltip - + 3 CHARACTER_TYPE_NONE + tooltip + type integer value - 4 - tooltip - + 4 CLICK_ACTION_BUY + tooltip + When the prim is clicked, the buy dialog is opened. type integer value - 2 + 2 + + CLICK_ACTION_DISABLED + tooltip - When the prim is clicked, the buy dialog is opened. + No click action. No touches detected or passed. + type + integer + value + 8 - CLICK_ACTION_NONE + CLICK_ACTION_IGNORE + tooltip + No click action. Object is invisible to the mouse. type integer value - 0 + 9 + + CLICK_ACTION_NONE + tooltip Performs the default action: when the prim is clicked, touch events are triggered. + type + integer + value + 0 CLICK_ACTION_OPEN + tooltip + When the prim is clicked, the object inventory dialog is opened. type integer value - 4 - tooltip - When the prim is clicked, the object inventory dialog is opened. + 4 CLICK_ACTION_OPEN_MEDIA + tooltip + When the prim is touched, the web media dialog is opened. type integer value - 6 - tooltip - When the prim is touched, the web media dialog is opened. + 6 CLICK_ACTION_PAY + tooltip + When the prim is clicked, the pay dialog is opened. type integer value - 3 - tooltip - When the prim is clicked, the pay dialog is opened. + 3 CLICK_ACTION_PLAY + tooltip + When the prim is clicked, html-on-a-prim is enabled? type integer value - 5 - tooltip - When the prim is clicked, html-on-a-prim is enabled? + 5 CLICK_ACTION_SIT - type - integer - value - 1 tooltip When the prim is clicked, the avatar sits upon it. + type + integer + value + 1 CLICK_ACTION_TOUCH + tooltip + When the prim is clicked, touch events are triggered. type integer value - 0 + 0 + + CLICK_ACTION_ZOOM + tooltip - When the prim is clicked, touch events are triggered. + Zoom in on object when clicked. + type + integer + value + 7 - CONTENT_TYPE_ATOM + COMBAT_CHANNEL + tooltip + COMBAT_CHANNEL is an integer constant that, when passed to llRegionSay will add the message to the combat log. A script with a chat listen active on COMBAT_CHANNEL may also monitor the combat log. type integer value - 4 + 2147483646 + + COMBAT_LOG_ID + tooltip - "application/atom+xml" + + type + string + value + 45e0fcfa-2268-4490-a51c-3e51bdfe80d1 - CONTENT_TYPE_FORM + CONTENT_TYPE_ATOM + tooltip + "application/atom+xml" type integer value - 7 + 4 + + CONTENT_TYPE_FORM + tooltip - "application/x-www-form-urlencoded" + "application/x-www-form-urlencoded" + type + integer + value + 7 CONTENT_TYPE_HTML + tooltip + "text/html", only valid for embedded browsers on content owned by the person viewing. Falls back to "text/plain" otherwise. type integer value - 1 - tooltip - "text/html", only valid for embedded browsers on content owned by the person viewing. Falls back to "text/plain" otherwise. + 1 CONTENT_TYPE_JSON + tooltip + "application/json" type integer value - 5 - tooltip - "application/json" + 5 CONTENT_TYPE_LLSD + tooltip + "application/llsd+xml" type integer value - 6 - tooltip - "application/llsd+xml" + 6 CONTENT_TYPE_RSS + tooltip + "application/rss+xml" type integer value - 8 - tooltip - "application/rss+xml" + 8 CONTENT_TYPE_TEXT + tooltip + "text/plain" type integer value - 0 - tooltip - "text/plain" + 0 CONTENT_TYPE_XHTML + tooltip + "application/xhtml+xml" type integer value - 3 - tooltip - "application/xhtml+xml" + 3 CONTENT_TYPE_XML + tooltip + "application/xml" type integer value - 2 - tooltip - "application/xml" + 2 CONTROL_BACK + tooltip + Test for the avatar move back control. type integer value 0x2 - tooltip - Test for the avatar move back control. CONTROL_DOWN + tooltip + Test for the avatar move down control. type integer value 0x20 - tooltip - Test for the avatar move down control. CONTROL_FWD + tooltip + Test for the avatar move forward control. type integer value 0x1 - tooltip - Test for the avatar move forward control. CONTROL_LBUTTON + tooltip + Test for the avatar left button control. type integer value 0x10000000 - tooltip - Test for the avatar left button control. CONTROL_LEFT + tooltip + Test for the avatar move left control. type integer value 0x4 - tooltip - Test for the avatar move left control. CONTROL_ML_LBUTTON + tooltip + Test for the avatar left button control while in mouse look. type integer value 0x40000000 - tooltip - Test for the avatar left button control while in mouse look. CONTROL_RIGHT + tooltip + Test for the avatar move right control. type integer value 0x8 - tooltip - Test for the avatar move right control. CONTROL_ROT_LEFT + tooltip + Test for the avatar rotate left control. type integer value 0x100 - tooltip - Test for the avatar rotate left control. CONTROL_ROT_RIGHT + tooltip + Test for the avatar rotate right control. type integer value 0x200 - tooltip - Test for the avatar rotate right control. CONTROL_UP + tooltip + Test for the avatar move up control. type integer value 0x10 - tooltip - Test for the avatar move up control. - DATA_BORN + DAMAGEABLE + tooltip + Objects in world that are able to process damage. type integer value - 3 - tooltip - The date the agent was born, returned in ISO 8601 format of YYYY-MM-DD. + 0x20 - DATA_NAME + DAMAGE_TYPE_ACID + tooltip + Damage caused by a caustic substance, such as acid type integer value - 2 - tooltip - The name of the agent. + 1 - DATA_ONLINE + DAMAGE_TYPE_BLUDGEONING + tooltip + Damage caused by a blunt object, such as a club. type integer value - 1 - tooltip - TRUE for online, FALSE for offline. + 2 - DATA_PAYINFO + DAMAGE_TYPE_COLD + tooltip + Damage inflicted by exposure to extreme cold type integer value - 8 - tooltip - + 3 - DATA_RATING + DAMAGE_TYPE_ELECTRIC + tooltip + Damage caused by electricity. type integer value - 4 - tooltip - Returns the agent ratings as a comma separated string of six integers. They are: - 1) Positive rated behaviour - 2) Negative rated behaviour - 3) Positive rated appearance - 4) Negative rated appearance - 5) Positive rated building - 6) Negative rated building + 4 - DATA_SIM_POS + DAMAGE_TYPE_EMOTIONAL + tooltip + type integer value - 5 - tooltip - + 14 - DATA_SIM_RATING + DAMAGE_TYPE_FIRE + tooltip + Damage inflicted by exposure to heat or flames. type integer value - 7 - tooltip - + 5 - DATA_SIM_STATUS + DAMAGE_TYPE_FORCE + tooltip + Damage inflicted by a great force or impact. type integer value - 6 - tooltip - + 6 - DEBUG_CHANNEL + DAMAGE_TYPE_GENERIC + tooltip + Generic or legacy damage. type integer value - 2147483647 - tooltip - DEBUG_CHANNEL is an integer constant that, when passed to llSay, llWhisper, or llShout as a channel parameter, will print text to the Script Warning/Error Window. + 0 - DEG_TO_RAD + DAMAGE_TYPE_IMPACT - type - float - value - 0.017453293 tooltip - 0.017453293 - Number of radians per degree. - You can use this to convert degrees to radians by multiplying the degrees by this number. - - DENSITY - + System damage generated by imapact with land or a prim. type integer value - 1 - tooltip - Used with llSetPhysicsMaterial to enable the density value. Must be between 1.0 and 22587.0 (in Kg/m^3 -- see if you can figure out what 22587 represents) + -1 - EOF + DAMAGE_TYPE_NECROTIC + tooltip + Damage caused by a direct assault on life-force type - string + integer value - \\n\\n\\n - tooltip - Indicates the last line of a notecard was read. + 7 - ERR_GENERIC + DAMAGE_TYPE_PIERCING + tooltip + Damage caused by a piercing object such as a bullet, spear, or arrow. type integer value - -1 - tooltip - + 8 - ERR_MALFORMED_PARAMS + DAMAGE_TYPE_POISON + tooltip + Damage caused by poison. type integer value - -3 - tooltip - + 9 - ERR_PARCEL_PERMISSIONS + DAMAGE_TYPE_PSYCHIC + tooltip + Damage caused by a direct assault on the mind. type integer value - -2 - tooltip - + 10 - ERR_RUNTIME_PERMISSIONS + DAMAGE_TYPE_RADIANT + tooltip + Damage caused by radiation or extreme light. type integer value - -4 - tooltip - + 11 - ERR_THROTTLED + DAMAGE_TYPE_SLASHING + tooltip + Damage caused by a slashing object such as a sword or axe. type integer value - -5 - tooltip - + 12 - ESTATE_ACCESS_ALLOWED_AGENT_ADD + DAMAGE_TYPE_SONIC + tooltip + Damage caused by loud noises, like a Crash Worship concert. type integer value - 4 - tooltip - Add the agent to this estate's Allowed Residents list. + 13 - ESTATE_ACCESS_ALLOWED_AGENT_REMOVE + DATA_BORN + tooltip + The date the agent was born, returned in ISO 8601 format of YYYY-MM-DD. type integer value - 8 - tooltip - Remove the agent from this estate's Allowed Residents list. + 3 - ESTATE_ACCESS_ALLOWED_GROUP_ADD + DATA_NAME + tooltip + The name of the agent. type integer value - 16 - tooltip - Add the group to this estate's Allowed groups list. + 2 - ESTATE_ACCESS_ALLOWED_GROUP_REMOVE + DATA_ONLINE + tooltip + TRUE for online, FALSE for offline. type integer value - 32 - tooltip - Remove the group from this estate's Allowed groups list. + 1 - ESTATE_ACCESS_BANNED_AGENT_ADD + DATA_PAYINFO + tooltip + type integer value - 64 - tooltip - Add the agent to this estate's Banned residents list. + 8 - ESTATE_ACCESS_BANNED_AGENT_REMOVE + DATA_RATING + tooltip + + Returns the agent ratings as a comma separated string of six integers. They are: + 1) Positive rated behaviour + 2) Negative rated behaviour + 3) Positive rated appearance + 4) Negative rated appearance + 5) Positive rated building + 6) Negative rated building + type integer value - 128 - tooltip - Remove the agent from this estate's Banned residents list. + 4 - FALSE + DATA_SIM_POS + tooltip + type integer value - 0 - tooltip - An integer constant for boolean comparisons. Has the value '0'. + 5 - FORCE_DIRECT_PATH + DATA_SIM_RATING + tooltip + type integer value - 1 - tooltip - Makes character navigate in a straight line toward position. May be set to TRUE or FALSE. + 7 - FRICTION + DATA_SIM_STATUS + tooltip + type integer value - 2 - tooltip - Used with llSetPhysicsMaterial to enable the friction value. Must be between 0.0 and 255.0 + 6 - GCNP_RADIUS + DEBUG_CHANNEL + tooltip + DEBUG_CHANNEL is an integer constant that, when passed to llSay, llWhisper, or llShout as a channel parameter, will print text to the Script Warning/Error Window. type integer value - 0 - tooltip - + 2147483647 - GCNP_STATIC + DEG_TO_RAD + tooltip + + 0.017453293 - Number of radians per degree. + You can use this to convert degrees to radians by multiplying the degrees by this number. + type - integer + float value - 1 - tooltip - + 0.017453293 - GRAVITY_MULTIPLIER + DENSITY + tooltip + Used with llSetPhysicsMaterial to enable the density value. Must be between 1.0 and 22587.0 (in Kg/m^3 -- see if you can figure out what 22587 represents) type integer value - 8 - tooltip - Used with llSetPhysicsMaterial to enable the gravity multiplier value. Must be between -1.0 and +28.0 + 1 - HORIZONTAL + DEREZ_DIE + tooltip + Causes the object to immediately die. type integer value - 1 - tooltip - + 0 - HTTP_BODY_MAXLENGTH + DEREZ_MAKE_TEMP + tooltip + The object is made temporary and will be cleaned up at some later timer. type integer value - 2 - tooltip - + 1 - HTTP_BODY_TRUNCATED + ENVIRONMENT_DAYINFO + tooltip + Day length, offset and progression. type integer value - 0 - tooltip - + 200 - HTTP_CUSTOM_HEADER + ENV_INVALID_AGENT + tooltip + Could not find agent with the specified ID type integer value - 5 - tooltip - Add an extra custom HTTP header to the request. The first string is the name of the parameter to change, e.g. "Pragma", and the second string is the value, e.g. "no-cache". Up to 8 custom headers may be configured per request. Note that certain headers, such as the default headers, are blocked for security reasons. + -4 - HTTP_METHOD + ENV_INVALID_RULE + tooltip + Attempted to change an unknown property. type integer value - 0 - tooltip - + -5 - HTTP_MIMETYPE + ENV_NOT_EXPERIENCE + tooltip + Attempt to change environments outside an experience. type integer value - 1 - tooltip - + -1 - HTTP_PRAGMA_NO_CACHE + ENV_NO_ENVIRONMENT + tooltip + Could not find environmental settings in object inventory. type integer value - 6 - tooltip - Allows enabling/disbling of the "Pragma: no-cache" header.\nUsage: [HTTP_PRAGMA_NO_CACHE, integer SendHeader]. When SendHeader is TRUE, the "Pragma: no-cache" header is sent by the script. This matches the default behavior. When SendHeader is FALSE, no "Pragma" header is sent by the script. + -3 - HTTP_VERBOSE_THROTTLE + ENV_NO_EXPERIENCE_LAND + tooltip + The experience has not been enabled on this land. type integer value - 4 - tooltip - + -7 - HTTP_VERIFY_CERT + ENV_NO_EXPERIENCE_PERMISSION + tooltip + Agent has not granted permission to change environments. type integer value - 3 - tooltip - + -2 - INVENTORY_ALL + ENV_NO_PERMISSIONS + tooltip + Script does not have permission to modify environment. type integer value - -1 - tooltip - + -9 - INVENTORY_ANIMATION + ENV_THROTTLE + tooltip + Could not validate values for environment. type integer value - 20 - tooltip - + -8 - INVENTORY_BODYPART + ENV_VALIDATION_FAIL + tooltip + Could not validate values for environment. type integer value - 13 - tooltip - + -6 - INVENTORY_CLOTHING + EOF + tooltip + Indicates the last line of a notecard was read. type - integer + string value - 5 - tooltip - + \\n\\n\\n - INVENTORY_GESTURE + ERR_GENERIC + tooltip + type integer value - 21 - tooltip - + -1 - INVENTORY_LANDMARK + ERR_MALFORMED_PARAMS + tooltip + type integer value - 3 - tooltip - + -3 - INVENTORY_NONE + ERR_PARCEL_PERMISSIONS + tooltip + type integer value - -1 - tooltip - + -2 - INVENTORY_NOTECARD + ERR_RUNTIME_PERMISSIONS + tooltip + type integer value - 7 - tooltip - + -4 - INVENTORY_OBJECT + ERR_THROTTLED + tooltip + type integer value - 6 - tooltip - + -5 - INVENTORY_SCRIPT + ESTATE_ACCESS_ALLOWED_AGENT_ADD + tooltip + Add the agent to this estate's Allowed Residents list. type integer value - 10 - tooltip - + 4 - INVENTORY_SETTING + ESTATE_ACCESS_ALLOWED_AGENT_REMOVE + tooltip + Remove the agent from this estate's Allowed Residents list. type integer value - 56 - tooltip - + 8 - INVENTORY_SOUND + ESTATE_ACCESS_ALLOWED_GROUP_ADD + tooltip + Add the group to this estate's Allowed groups list. type integer value - 1 - tooltip - + 16 - INVENTORY_TEXTURE + ESTATE_ACCESS_ALLOWED_GROUP_REMOVE + tooltip + Remove the group from this estate's Allowed groups list. type integer value - 0 - tooltip - + 32 - INVENTORY_MATERIAL + ESTATE_ACCESS_BANNED_AGENT_ADD + tooltip + Add the agent to this estate's Banned residents list. type integer value - 57 - tooltip - + 64 - JSON_APPEND + ESTATE_ACCESS_BANNED_AGENT_REMOVE + tooltip + Remove the agent from this estate's Banned residents list. type integer value - -1 - tooltip - + 128 - JSON_ARRAY + FALSE - type - string - value - U+FDD2 tooltip - - - JSON_DELETE - + An integer constant for boolean comparisons. Has the value '0'. type - string + integer value - U+FDD8 - tooltip - + 0 - JSON_FALSE + FILTER_FLAGS + tooltip + Flags to control returned attachments. type - string + integer value - U+FDD7 - tooltip - + 2 - JSON_INVALID + FILTER_FLAG_HUDS + tooltip + Include HUDs with matching experience. type - string + integer value - U+FDD0 - tooltip - + 0x0001 - JSON_NULL + FILTER_INCLUDE + tooltip + Include attachment point. type - string + integer value - U+FDD5 - tooltip - + 1 - JSON_NUMBER + FORCE_DIRECT_PATH + tooltip + Makes character navigate in a straight line toward position. May be set to TRUE or FALSE. type - string + integer value - U+FDD3 - tooltip - + 1 - JSON_OBJECT + FRICTION + tooltip + Used with llSetPhysicsMaterial to enable the friction value. Must be between 0.0 and 255.0 type - string + integer value - U+FDD1 - tooltip - + 2 - JSON_STRING + GAME_CONTROL_AXIS_LEFTX + tooltip + type - string + integer value - U+FDD4 - tooltip - + 0 - JSON_TRUE + GAME_CONTROL_AXIS_LEFTY + tooltip + type - string + integer value - U+FDD6 - tooltip - + 1 - KFM_CMD_PAUSE + GAME_CONTROL_AXIS_RIGHTX + tooltip + type integer value - 2 - tooltip - For use with KFM_COMMAND. + 2 - KFM_CMD_PLAY + GAME_CONTROL_AXIS_RIGHTY + tooltip + type integer value - 0 - tooltip - For use with KFM_COMMAND. + 3 - KFM_CMD_STOP + GAME_CONTROL_AXIS_TRIGGERLEFT + tooltip + type integer value - 1 - tooltip - For use with KFM_COMMAND. + 4 - KFM_COMMAND + GAME_CONTROL_AXIS_TRIGGERRIGHT + tooltip + type integer value - 0 - tooltip - + 5 - KFM_DATA + GAME_CONTROL_BUTTON_A + tooltip + type integer value - 2 - tooltip - + 0x1 - KFM_FORWARD + GAME_CONTROL_BUTTON_B + tooltip + type integer value - 0 - tooltip - For use with KFM_MODE. + 0x2 - KFM_LOOP + GAME_CONTROL_BUTTON_BACK + tooltip + type integer value - 1 - tooltip - For use with KFM_MODE. + 0x10 - KFM_MODE + GAME_CONTROL_BUTTON_DPAD_DOWN + tooltip + type integer value - 1 - tooltip - + 0x1000 - KFM_PING_PONG + GAME_CONTROL_BUTTON_DPAD_LEFT + tooltip + type integer value - 2 - tooltip - For use with KFM_MODE. + 0x2000 - KFM_REVERSE + GAME_CONTROL_BUTTON_DPAD_RIGHT + tooltip + type integer value - 3 - tooltip - For use with KFM_MODE. + 0x4000 - KFM_ROTATION + GAME_CONTROL_BUTTON_DPAD_UP + tooltip + type integer value - 1 - tooltip - For use with KFM_DATA. + 0x800 - KFM_TRANSLATION + GAME_CONTROL_BUTTON_GUIDE + tooltip + type integer value - 2 - tooltip - For use with KFM_DATA. + 0x20 - LAND_LARGE_BRUSH + GAME_CONTROL_BUTTON_LEFTSHOULDER + tooltip + type integer value - 3 - tooltip - Use a large brush size.\nNOTE: This value is incorrect, a large brush should be 2. + 0x200 - LAND_LEVEL + GAME_CONTROL_BUTTON_LEFTSTICK + tooltip + type integer value - 0 - tooltip - Action to level the land. + 0x80 - LAND_LOWER + GAME_CONTROL_BUTTON_MISC1 + tooltip + type integer value - 2 - tooltip - Action to lower the land. + 0x8000 - LAND_MEDIUM_BRUSH + GAME_CONTROL_BUTTON_PADDLE1 + tooltip + type integer value - 2 - tooltip - Use a medium brush size.\nNOTE: This value is incorrect, a medium brush should be 1. + 0x10000 - LAND_NOISE + GAME_CONTROL_BUTTON_PADDLE2 + tooltip + type integer value - 4 - tooltip - + 0x20000 - LAND_RAISE + GAME_CONTROL_BUTTON_PADDLE3 + tooltip + type integer value - 1 - tooltip - Action to raise the land. + 0x40000 - LAND_REVERT + GAME_CONTROL_BUTTON_PADDLE4 + tooltip + type integer value - 5 - tooltip - + 0x80000 - LAND_SMALL_BRUSH + GAME_CONTROL_BUTTON_RIGHTSHOULDER + tooltip + type integer value - 1 - tooltip - Use a small brush size.\nNOTE: This value is incorrect, a small brush should be 0. + 0x400 - LAND_SMOOTH + GAME_CONTROL_BUTTON_RIGHTSTICK + tooltip + type integer value - 3 - tooltip - + 0x100 - LINK_ALL_CHILDREN + GAME_CONTROL_BUTTON_START + tooltip + type integer value - -3 - tooltip - This targets every object except the root in the linked set. + 0x40 - LINK_ALL_OTHERS + GAME_CONTROL_BUTTON_TOUCHPAD + tooltip + type integer value - -2 - tooltip - This targets every object in the linked set except the object with the script. + 0x100000 - LINK_ROOT + GAME_CONTROL_BUTTON_X + tooltip + type integer value - 1 - tooltip - This targets the root of the linked set. + 0x4 - LINK_SET + GAME_CONTROL_BUTTON_Y + tooltip + type integer value - -1 - tooltip - This targets every object in the linked set. + 0x8 - LINK_THIS + GCNP_RADIUS + tooltip + type integer value - -4 - tooltip - The link number of the prim containing the script. + 0 - LIST_STAT_GEOMETRIC_MEAN + GCNP_STATIC + tooltip + type integer value - 9 - tooltip - + 1 - LIST_STAT_MAX + GRAVITY_MULTIPLIER + tooltip + Used with llSetPhysicsMaterial to enable the gravity multiplier value. Must be between -1.0 and +28.0 type integer value - 2 - tooltip - + 8 - LIST_STAT_MEAN + HORIZONTAL + tooltip + type integer value - 3 - tooltip - + 1 - LIST_STAT_MEDIAN + HTTP_ACCEPT + tooltip + + Provide a string value to be included in the HTTP + accepts header value. This replaces the default Second Life HTTP accepts header. + type integer value - 4 - tooltip - + 8 - LIST_STAT_MIN + HTTP_BODY_MAXLENGTH + tooltip + type integer value - 1 - tooltip - + 2 - LIST_STAT_NUM_COUNT + HTTP_BODY_TRUNCATED + tooltip + type integer value - 8 - tooltip - + 0 - LIST_STAT_RANGE + HTTP_CUSTOM_HEADER + tooltip + Add an extra custom HTTP header to the request. The first string is the name of the parameter to change, e.g. "Pragma", and the second string is the value, e.g. "no-cache". Up to 8 custom headers may be configured per request. Note that certain headers, such as the default headers, are blocked for security reasons. type integer value - 0 - tooltip - + 5 - LIST_STAT_STD_DEV + HTTP_EXTENDED_ERROR + tooltip + Report extended error information through http_response event. type integer value - 5 - tooltip - + 9 - LIST_STAT_SUM + HTTP_METHOD + tooltip + type integer value - 6 - tooltip - + 0 - LIST_STAT_SUM_SQUARES + HTTP_MIMETYPE + tooltip + type integer value - 7 - tooltip - + 1 - LOOP + HTTP_PRAGMA_NO_CACHE + tooltip + Allows enabling/disbling of the "Pragma: no-cache" header.\nUsage: [HTTP_PRAGMA_NO_CACHE, integer SendHeader]. When SendHeader is TRUE, the "Pragma: no-cache" header is sent by the script. This matches the default behavior. When SendHeader is FALSE, no "Pragma" header is sent by the script. type integer value - 0x2 - tooltip - Loop the texture animation. + 6 - MASK_BASE + HTTP_USER_AGENT + tooltip + + Provide a string value to be included in the HTTP + User-Agent header value. This is appended to the default value. + type integer value - 0 - tooltip - + 7 - MASK_EVERYONE + HTTP_VERBOSE_THROTTLE + tooltip + type integer value - 3 - tooltip - + 4 - MASK_GROUP + HTTP_VERIFY_CERT + tooltip + type integer value - 2 - tooltip - + 3 - MASK_NEXT + IMG_USE_BAKED_AUX1 + tooltip + type - integer + string value - 4 - tooltip - + 9742065b-19b5-297c-858a-29711d539043 - MASK_OWNER + IMG_USE_BAKED_AUX2 + tooltip + type - integer + string value - 1 - tooltip - + 03642e83-2bd1-4eb9-34b4-4c47ed586d2d - NULL_KEY + IMG_USE_BAKED_AUX3 + tooltip + type string value - 00000000-0000-0000-0000-000000000000 - tooltip - + edd51b77-fc10-ce7a-4b3d-011dfc349e4f - OBJECT_ATTACHED_POINT + IMG_USE_BAKED_EYES + tooltip + type - integer + string value - 19 - tooltip - Gets the attachment point to which the object is attached.\nReturns 0 if the object is not an attachment (or is an avatar, etc). + 52cc6bb6-2ee5-e632-d3ad-50197b1dcb8a - OBJECT_BODY_SHAPE_TYPE + IMG_USE_BAKED_HAIR + tooltip + type - integer + string value - 26 - tooltip - This is a flag used with llGetObjectDetails to get the body type of the avatar, based on shape data.\nIf no data is available, -1.0 is returned.\nThis is normally between 0 and 1.0, with 0.5 and larger considered 'male' + 09aac1fb-6bce-0bee-7d44-caac6dbb6c63 - OBJECT_CHARACTER_TIME + IMG_USE_BAKED_HEAD + tooltip + type - integer + string value - 17 - tooltip - Units in seconds + 5a9f4a74-30f2-821c-b88d-70499d3e7183 - OBJECT_CLICK_ACTION + IMG_USE_BAKED_LEFTARM + tooltip + type - integer + string value - 28 - tooltip - This is a flag used with llGetObjectDetails to get the click action.\nThe default is 0 + ff62763f-d60a-9855-890b-0c96f8f8cd98 - OBJECT_CREATOR + IMG_USE_BAKED_LEFTLEG + tooltip + type - integer + string value - 8 - tooltip - Gets the object's creator key. If id is an avatar, a NULL_KEY is returned. + 8e915e25-31d1-cc95-ae08-d58a47488251 - OBJECT_DESC + IMG_USE_BAKED_LOWER + tooltip + type - integer + string value - 2 - tooltip - Gets the object's description. If id is an avatar, an empty string is returned. + 24daea5f-0539-cfcf-047f-fbc40b2786ba - OBJECT_GROUP + IMG_USE_BAKED_SKIRT + tooltip + type - integer + string value - 7 - tooltip - Gets the prims's group key. If id is an avatar, a NULL_KEY is returned. + 43529ce8-7faa-ad92-165a-bc4078371687 - OBJECT_HOVER_HEIGHT + IMG_USE_BAKED_UPPER + tooltip + type - integer + string value - 25 - tooltip - This is a flag used with llGetObjectDetails to get hover height of the avatar\nIf no data is available, 0.0 is returned. + ae2de45c-d252-50b8-5c6e-19f39ce79317 - OBJECT_LAST_OWNER_ID + INVENTORY_ALL + tooltip + type integer value - 27 - tooltip - Gets the object's last owner ID. + -1 - OBJECT_NAME + INVENTORY_ANIMATION + tooltip + type integer value - 1 - tooltip - Gets the object's name. + 20 - OBJECT_OMEGA + INVENTORY_BODYPART + tooltip + type integer value - 29 - tooltip - Gets an object's angular velocity. + 13 - OBJECT_OWNER + INVENTORY_CLOTHING + tooltip + type integer value - 6 - tooltip - Gets an object's owner's key. If id is group owned, a NULL_KEY is returned. + 5 - OBJECT_PRIM_COUNT + INVENTORY_GESTURE + tooltip + type integer value - 30 - tooltip - Gets the prim count of the object. The script and target object must be owned by the same owner + 21 - OBJECT_PATHFINDING_TYPE + INVENTORY_LANDMARK + tooltip + type integer value - 20 - tooltip - Returns the pathfinding setting of any object in the region. It returns an integer matching one of the OPT_* constants. + 3 - OBJECT_PHANTOM + INVENTORY_MATERIAL + tooltip + type integer value - 22 - tooltip - Returns boolean, detailing if phantom is enabled or disabled on the object.\nIf id is an avatar or attachment, 0 is returned. + 57 - OBJECT_PHYSICS + INVENTORY_NONE + tooltip + type integer value - 21 - tooltip - Returns boolean, detailing if physics is enabled or disabled on the object.\nIf id is an avatar or attachment, 0 is returned. + -1 - OBJECT_PHYSICS_COST + INVENTORY_NOTECARD + tooltip + type integer value - 16 - tooltip - + 7 - OBJECT_POS + INVENTORY_OBJECT + tooltip + type integer value - 3 - tooltip - Gets the object's position in region coordinates. + 6 - OBJECT_PRIM_EQUIVALENCE + INVENTORY_SCRIPT + tooltip + type integer value - 13 - tooltip - + 10 - OBJECT_RENDER_WEIGHT + INVENTORY_SETTING + tooltip + type integer value - 24 - tooltip - This is a flag used with llGetObjectDetails to get the Avatar_Rendering_Cost of an avatar, based on values reported by nearby viewers.\nIf no data is available, -1 is returned.\nThe maximum render weight stored by the simulator is 500000. When called against an object, 0 is returned. + 56 - OBJECT_RETURN_PARCEL + INVENTORY_SOUND + tooltip + type integer value - 1 - tooltip - + 1 - OBJECT_RETURN_PARCEL_OWNER + INVENTORY_TEXTURE + tooltip + type integer value - 2 - tooltip - + 0 - OBJECT_RETURN_REGION + JSON_APPEND + tooltip + type integer value - 4 - tooltip - + -1 - OBJECT_REZZER_KEY + JSON_ARRAY + tooltip + type - integer + string value - 32 - tooltip - + \\ufdd2 - OBJECT_ROOT + JSON_DELETE + tooltip + type - integer + string value - 18 - tooltip - Gets the id of the root prim of the object requested.\nIf id is an avatar, return the id of the root prim of the linkset the avatar is sitting on (or the avatar's own id if the avatar is not sitting on an object within the region). + \\ufdd8 - OBJECT_ROT + JSON_FALSE + tooltip + type - integer + string value - 4 - tooltip - Gets the object's rotation. + \\ufdd7 - OBJECT_RUNNING_SCRIPT_COUNT + JSON_INVALID + tooltip + type - integer + string value - 9 - tooltip - + \\ufdd0 - OBJECT_SCRIPT_MEMORY + JSON_NULL + tooltip + type - integer + string value - 11 - tooltip - + \\ufdd5 - OBJECT_SCRIPT_TIME + JSON_NUMBER + tooltip + type - integer + string value - 12 - tooltip - + \\ufdd3 - OBJECT_SERVER_COST + JSON_OBJECT + tooltip + type - integer + string value - 14 - tooltip - + \\ufdd1 - OBJECT_STREAMING_COST + JSON_STRING + tooltip + type - integer + string value - 15 - tooltip - + \\ufdd4 - OBJECT_TEMP_ON_REZ + JSON_TRUE + tooltip + type - integer + string value - 23 - tooltip - Returns boolean, detailing if temporary is enabled or disabled on the object. + \\ufdd6 - OBJECT_TOTAL_INVENTORY_COUNT + KFM_CMD_PAUSE + tooltip + For use with KFM_COMMAND. type integer value - 31 - tooltip - Gets the total inventory count of the object. The script and target object must be owned by the same owner + 2 - OBJECT_TOTAL_SCRIPT_COUNT + KFM_CMD_PLAY + tooltip + For use with KFM_COMMAND. type integer value - 10 - tooltip - + 0 - OBJECT_UNKNOWN_DETAIL + KFM_CMD_STOP + tooltip + For use with KFM_COMMAND. type integer value - -1 - tooltip - + 1 - OBJECT_VELOCITY + KFM_COMMAND + tooltip + type integer value - 5 - tooltip - Gets the object's velocity. + 0 - OPT_AVATAR + KFM_DATA + tooltip + type integer value - 1 - tooltip - Returned for avatars. + 2 - OPT_CHARACTER + KFM_FORWARD + tooltip + For use with KFM_MODE. type integer value - 2 - tooltip - Returned for pathfinding characters. + 0 - OPT_EXCLUSION_VOLUME + KFM_LOOP + tooltip + For use with KFM_MODE. type integer value - 6 - tooltip - Returned for exclusion volumes. + 1 - OPT_LEGACY_LINKSET + KFM_MODE + tooltip + type integer value - 0 - tooltip - Returned for movable obstacles, movable phantoms, physical, and volumedetect objects. + 1 - OPT_MATERIAL_VOLUME + KFM_PING_PONG + tooltip + For use with KFM_MODE. type integer value - 5 - tooltip - Returned for material volumes. + 2 - OPT_OTHER + KFM_REVERSE + tooltip + For use with KFM_MODE. type integer value - -1 - tooltip - Returned for attachments, Linden trees, and grass. + 3 - OPT_STATIC_OBSTACLE + KFM_ROTATION + tooltip + For use with KFM_DATA. type integer value - 4 - tooltip - Returned for static obstacles. + 1 - OPT_WALKABLE + KFM_TRANSLATION + tooltip + For use with KFM_DATA. type integer value - 3 - tooltip - Returned for walkable objects. + 2 - PARCEL_COUNT_GROUP + LAND_LARGE_BRUSH + tooltip + Use a large brush size.\nNOTE: This value is incorrect, a large brush should be 2. type integer value - 2 - tooltip - + 3 - PARCEL_COUNT_OTHER + LAND_LEVEL + tooltip + Action to level the land. type integer value - 3 - tooltip - + 0 - PARCEL_COUNT_OWNER + LAND_LOWER + tooltip + Action to lower the land. type integer value - 1 - tooltip - + 2 - PARCEL_COUNT_SELECTED + LAND_MEDIUM_BRUSH + tooltip + Use a medium brush size.\nNOTE: This value is incorrect, a medium brush should be 1. type integer value - 4 - tooltip - + 2 - PARCEL_COUNT_TEMP + LAND_NOISE + tooltip + type integer value - 5 - tooltip - + 4 - PARCEL_COUNT_TOTAL + LAND_RAISE + tooltip + Action to raise the land. type integer value - 0 - tooltip - + 1 - PARCEL_DETAILS_AREA + LAND_REVERT + tooltip + type integer value - 4 - tooltip - The parcel's area, in square meters. (5 chars.). + 5 - PARCEL_DETAILS_DESC + LAND_SMALL_BRUSH + tooltip + Use a small brush size.\nNOTE: This value is incorrect, a small brush should be 0. type integer value - 1 - tooltip - The description of the parcel. (127 chars). + 1 - PARCEL_DETAILS_GROUP + LAND_SMOOTH + tooltip + type integer value - 3 - tooltip - The parcel group's key. (36 chars.). + 3 - PARCEL_DETAILS_ID + LINKSETDATA_DELETE + tooltip + A name:value pair has been removed from the linkset datastore. type integer value - 5 - tooltip - The parcel's key. (36 chars.). + 2 - PARCEL_DETAILS_NAME + LINKSETDATA_EMEMORY + tooltip + A name:value pair was too large to write to the linkset datastore. type integer value - 0 - tooltip - The name of the parcel. (63 chars.). + 1 - PARCEL_DETAILS_OWNER + LINKSETDATA_ENOKEY + tooltip + The key supplied was empty. type integer value - 2 - tooltip - The parcel owner's key. (36 chars.). + 2 - PARCEL_DETAILS_SEE_AVATARS + LINKSETDATA_EPROTECTED + tooltip + The name:value pair has been protected from overwrite in the linkset datastore. type integer value - 6 - tooltip - The parcel's avatar visibility setting. (1 char.). + 3 - PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY + LINKSETDATA_MULTIDELETE + tooltip + A CSV list of names removed from the linkset datastore. type integer value - 0x08000000 - tooltip - + 3 - PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS + LINKSETDATA_NOTFOUND + tooltip + The named key was not found in the datastore. type integer value - 0x4000000 - tooltip - + 4 - PARCEL_FLAG_ALLOW_CREATE_OBJECTS + LINKSETDATA_NOUPDATE + tooltip + The value written to a name in the keystore is the same as the value already there. type integer value - 0x40 - tooltip - + 5 - PARCEL_FLAG_ALLOW_DAMAGE + LINKSETDATA_OK + tooltip + The name:value pair was written to the datastore. type integer value - 0x20 - tooltip - + 0 - PARCEL_FLAG_ALLOW_FLY + LINKSETDATA_RESET + tooltip + The linkset datastore has been reset. type integer value - 0x1 - tooltip - + 0 - PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY + LINKSETDATA_UPDATE + tooltip + A name:value pair in the linkset datastore has been changed or created. type integer value - 0x10000000 - tooltip - + 1 - PARCEL_FLAG_ALLOW_GROUP_SCRIPTS + LINK_ALL_CHILDREN + tooltip + This targets every object except the root in the linked set. type integer value - 0x2000000 - tooltip - + -3 - PARCEL_FLAG_ALLOW_LANDMARK + LINK_ALL_OTHERS + tooltip + This targets every object in the linked set except the object with the script. type integer value - 0x8 - tooltip - + -2 - PARCEL_FLAG_ALLOW_SCRIPTS + LINK_ROOT + tooltip + This targets the root of the linked set. type integer value - 0x2 - tooltip - + 1 - PARCEL_FLAG_ALLOW_TERRAFORM + LINK_SET + tooltip + This targets every object in the linked set. type integer value - 0x10 - tooltip - + -1 - PARCEL_FLAG_LOCAL_SOUND_ONLY + LINK_THIS + tooltip + The link number of the prim containing the script. type integer value - 0x8000 - tooltip - + -4 - PARCEL_FLAG_RESTRICT_PUSHOBJECT + LIST_STAT_GEOMETRIC_MEAN + tooltip + type integer value - 0x200000 - tooltip - + 9 - PARCEL_FLAG_USE_ACCESS_GROUP + LIST_STAT_MAX + tooltip + type integer value - 0x100 - tooltip - + 2 - PARCEL_FLAG_USE_ACCESS_LIST + LIST_STAT_MEAN + tooltip + type integer value - 0x200 - tooltip - + 3 - PARCEL_FLAG_USE_BAN_LIST + LIST_STAT_MEDIAN + tooltip + type integer value - 0x400 - tooltip - + 4 - PARCEL_FLAG_USE_LAND_PASS_LIST + LIST_STAT_MIN + tooltip + type integer value - 0x800 - tooltip - + 1 - PARCEL_MEDIA_COMMAND_AGENT + LIST_STAT_NUM_COUNT + tooltip + type integer value - 7 - tooltip - + 8 - PARCEL_MEDIA_COMMAND_AUTO_ALIGN + LIST_STAT_RANGE + tooltip + type integer value - 9 - tooltip - + 0 - PARCEL_MEDIA_COMMAND_DESC + LIST_STAT_STD_DEV + tooltip + type integer value - 12 - tooltip - Use this to get or set the parcel media description. + 5 - PARCEL_MEDIA_COMMAND_LOOP + LIST_STAT_SUM + tooltip + type integer value - 3 - tooltip - + 6 - PARCEL_MEDIA_COMMAND_LOOP_SET + LIST_STAT_SUM_SQUARES + tooltip + type integer value - 13 - tooltip - Used to get or set the parcel's media looping variable. + 7 - PARCEL_MEDIA_COMMAND_PAUSE + LOOP + tooltip + Loop the texture animation. type integer value - 1 - tooltip - + 0x2 - PARCEL_MEDIA_COMMAND_PLAY + MASK_BASE + tooltip + type integer value - 2 - tooltip - + 0 - PARCEL_MEDIA_COMMAND_SIZE + MASK_COMBINED + tooltip + Fold permissions for object inventory into results. type integer value - 11 - tooltip - Use this to get or set the parcel media pixel resolution. + 0x10 - PARCEL_MEDIA_COMMAND_STOP + MASK_EVERYONE + tooltip + type integer value - 0 - tooltip - + 3 - PARCEL_MEDIA_COMMAND_TEXTURE + MASK_GROUP + tooltip + type integer value - 4 - tooltip - + 2 - PARCEL_MEDIA_COMMAND_TIME + MASK_NEXT + tooltip + type integer value - 6 - tooltip - + 4 - PARCEL_MEDIA_COMMAND_TYPE + MASK_OWNER + tooltip + type integer value - 10 - tooltip - Use this to get or set the parcel media MIME type (e.g. "text/html"). + 1 - PARCEL_MEDIA_COMMAND_UNLOAD + NAK + tooltip + Indicates a notecard read was attempted and the notecard was not yet cached on the server. type - integer + string value - 8 - tooltip - + \\n\\x15\\n - PARCEL_MEDIA_COMMAND_URL + NULL_KEY + tooltip + type - integer + string value - 5 - tooltip - + 00000000-0000-0000-0000-000000000000 - PASS_ALWAYS + OBJECT_ACCOUNT_LEVEL + tooltip + Retrieves the account level of an avatar.\nReturns 0 when the avatar has a basic account,\n 1 when the avatar has a premium account,\n 10 when the avatar has a premium plus account,\n or -1 if the object is not an avatar. type integer value - 1 - tooltip - Always pass the event. + 41 - PASS_NEVER + OBJECT_ANIMATED_COUNT + tooltip + This is a flag used with llGetObjectDetails to get the number of associated animated objects type integer value - 2 - tooltip - Always pass the event. + 39 - PASS_IF_NOT_HANDLED + OBJECT_ANIMATED_SLOTS_AVAILABLE + tooltip + This is a flag used with llGetObjectDetails to get the number of additional animated object attachments allowed. type integer value - 0 - tooltip - Pass the event if there is no script handling the event in the prim. + 40 - PASSIVE + OBJECT_ATTACHED_POINT + tooltip + Gets the attachment point to which the object is attached.\nReturns 0 if the object is not an attachment (or is an avatar, etc). type integer value - 0x4 - tooltip - Static in-world objects. + 19 - PATROL_PAUSE_AT_WAYPOINTS + OBJECT_ATTACHED_SLOTS_AVAILABLE + tooltip + Returns the number of attachment slots available.\nReturns 0 if the object is not an avatar or none are available. type integer value - 0 - tooltip - + 35 - PAY_DEFAULT + OBJECT_BODY_SHAPE_TYPE + tooltip + This is a flag used with llGetObjectDetails to get the body type of the avatar, based on shape data.\nIf no data is available, -1.0 is returned.\nThis is normally between 0 and 1.0, with 0.5 and larger considered 'male' type integer value - -2 - tooltip - + 26 - PAY_HIDE + OBJECT_CHARACTER_TIME + tooltip + Units in seconds type integer value - -1 - tooltip - + 17 - PAYMENT_INFO_ON_FILE + OBJECT_CLICK_ACTION + tooltip + This is a flag used with llGetObjectDetails to get the click action.\nThe default is 0 type integer value - 1 - tooltip - + 28 - PAYMENT_INFO_USED + OBJECT_CREATION_TIME + tooltip + This is a flag used with llGetObjectDetails to get the time this object was created type integer value - 2 - tooltip - + 36 - PERM_ALL + OBJECT_CREATOR + tooltip + Gets the object's creator key. If id is an avatar, a NULL_KEY is returned. type integer value - 0x7FFFFFFF - tooltip - + 8 - PERM_COPY + OBJECT_DAMAGE + tooltip + Gets the damage value assigned to this object. type integer value - 0x8000 - tooltip - + 51 - PERM_MODIFY + OBJECT_DAMAGE_TYPE + tooltip + Gets the damage type, if any, assigned to this object. type integer value - 0x4000 - tooltip - + 52 - PERM_MOVE + OBJECT_DESC + tooltip + Gets the object's description. If id is an avatar, an empty string is returned. type integer value - 0x80000 - tooltip - + 2 - PERM_TRANSFER + OBJECT_GROUP + tooltip + Gets the prims's group key. If id is an avatar, a NULL_KEY is returned. type integer value - 0x2000 - tooltip - + 7 - PERMISSION_ATTACH + OBJECT_GROUP_TAG + tooltip + Gets the agent's current group role tag. If id is an object, an empty is returned. type integer value - 0x20 - tooltip - If this permission is enabled, the object can successfully call llAttachToAvatar to attach to the given avatar. + 33 - PERMISSION_CHANGE_JOINTS + OBJECT_HEALTH + tooltip + Gets current health value for the object. type integer value - 0x100 - tooltip - (not yet implemented) + 50 - PERMISSION_CHANGE_LINKS + OBJECT_HOVER_HEIGHT + tooltip + This is a flag used with llGetObjectDetails to get hover height of the avatar\nIf no data is available, 0.0 is returned. type integer value - 0x80 - tooltip - If this permission is enabled, the object can successfully call llCreateLink, llBreakLink, and llBreakAllLinks to change links to other objects. + 25 - PERMISSION_CHANGE_PERMISSIONS + OBJECT_LAST_OWNER_ID + tooltip + Gets the object's last owner ID. type integer value - 0x200 - tooltip - (not yet implemented) + 27 - PERMISSION_CONTROL_CAMERA + OBJECT_LINK_NUMBER + tooltip + Gets the object's link number or 0 if unlinked. type integer value - 0x800 - tooltip - + 46 - PERMISSION_DEBIT + OBJECT_MASS + tooltip + Get the object's mass type integer value - 0x2 - tooltip - If this permission is enabled, the object can successfully call llGiveMoney or llTransferLindenDollars to debit the owners account. + 43 - PERMISSION_OVERRIDE_ANIMATIONS + OBJECT_MATERIAL + tooltip + Get an object's material setting. type integer value - 0x8000 - tooltip - Permission to override default animations. + 42 - PERMISSION_RELEASE_OWNERSHIP + OBJECT_NAME + tooltip + Gets the object's name. type integer value - 0x40 - tooltip - (not yet implemented) + 1 - PERMISSION_REMAP_CONTROLS + OBJECT_OMEGA + tooltip + Gets an object's angular velocity. type integer value - 0x8 - tooltip - (not yet implemented) + 29 - PERMISSION_RETURN_OBJECTS + OBJECT_OWNER + tooltip + Gets an object's owner's key. If id is group owned, a NULL_KEY is returned. type integer value - 65536 - tooltip - + 6 - PERMISSION_SILENT_ESTATE_MANAGEMENT + OBJECT_PATHFINDING_TYPE + tooltip + Returns the pathfinding setting of any object in the region. It returns an integer matching one of the OPT_* constants. type integer value - 0x4000 - tooltip - A script with this permission does not notify the object owner when it modifies estate access rules via llManageEstateAccess. + 20 - PERMISSION_TAKE_CONTROLS + OBJECT_PERMS + tooltip + Gets the objects permissions type integer value - 0x4 - tooltip - If this permission enabled, the object can successfully call the llTakeControls libray call. + 53 - PERMISSION_TELEPORT + OBJECT_PERMS_COMBINED + tooltip + Gets the object's permissions including any inventory. type integer value - 0x1000 - tooltip - + 54 - PERMISSION_TRACK_CAMERA + OBJECT_PHANTOM + tooltip + Returns boolean, detailing if phantom is enabled or disabled on the object.\nIf id is an avatar or attachment, 0 is returned. type integer value - 0x400 - tooltip - + 22 - PERMISSION_TRIGGER_ANIMATION + OBJECT_PHYSICS + tooltip + Returns boolean, detailing if physics is enabled or disabled on the object.\nIf id is an avatar or attachment, 0 is returned. type integer value - 0x10 - tooltip - If this permission is enabled, the object can successfully call llStartAnimation for the avatar that owns this. + 21 - PI + OBJECT_PHYSICS_COST - type - float - value - 3.14159265 tooltip - 3.14159265 - The number of radians in a semi-circle. - - PI_BY_TWO - + type - float + integer value - 1.57079633 - tooltip - 1.57079633 - The number of radians in a quarter circle. + 16 - PING_PONG + OBJECT_POS + tooltip + Gets the object's position in region coordinates. type integer value - 0x8 - tooltip - Play animation going forwards, then backwards. + 3 - PRIM_ALPHA_MODE + OBJECT_PRIM_COUNT + tooltip + Gets the prim count of the object. The script and target object must be owned by the same owner type integer value - 38 - tooltip - Prim parameter for materials using integer face, integer alpha_mode, integer alpha_cutoff.\nDefines how the alpha channel of the diffuse texture should be rendered.\nValid options for alpha_mode are PRIM_ALPHA_MODE_BLEND, _NONE, _MASK, and _EMISSIVE.\nalpha_cutoff is used only for PRIM_ALPHA_MODE_MASK. + 30 - PRIM_ALPHA_MODE_NONE + OBJECT_PRIM_EQUIVALENCE + tooltip + type integer value - 0 - tooltip - Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be ignored. + 13 - PRIM_ALPHA_MODE_BLEND + OBJECT_RENDER_WEIGHT + tooltip + This is a flag used with llGetObjectDetails to get the Avatar_Rendering_Cost of an avatar, based on values reported by nearby viewers.\nIf no data is available, -1 is returned.\nThe maximum render weight stored by the simulator is 500000. When called against an object, 0 is returned. type integer value - 1 - tooltip - Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as alpha-blended. + 24 - PRIM_ALPHA_MODE_MASK + OBJECT_RETURN_PARCEL + tooltip + type integer value - 2 - tooltip - Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as fully opaque for alpha values above alpha_cutoff and fully transparent otherwise. + 1 - PRIM_ALPHA_MODE_EMISSIVE + OBJECT_RETURN_PARCEL_OWNER + tooltip + type integer value - 3 - tooltip - Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as an emissivity mask. + 2 - PRIM_BUMP_BARK + OBJECT_RETURN_REGION + tooltip + type integer value - 4 - tooltip - + 4 - PRIM_BUMP_BLOBS + OBJECT_REZZER_KEY + tooltip + type integer value - 12 - tooltip - + 32 - PRIM_BUMP_BRICKS + OBJECT_REZ_TIME + tooltip + Get the time when an object was rezzed. type integer value - 5 - tooltip - + 45 - PRIM_BUMP_BRIGHT + OBJECT_ROOT + tooltip + Gets the id of the root prim of the object requested.\nIf id is an avatar, return the id of the root prim of the linkset the avatar is sitting on (or the avatar's own id if the avatar is not sitting on an object within the region). type integer value - 1 - tooltip - + 18 - PRIM_BUMP_CHECKER + OBJECT_ROT + tooltip + Gets the object's rotation. type integer value - 6 - tooltip - + 4 - PRIM_BUMP_CONCRETE + OBJECT_RUNNING_SCRIPT_COUNT + tooltip + type integer value - 7 - tooltip - + 9 - PRIM_BUMP_DARK + OBJECT_SCALE + tooltip + Gets the object's size. type integer value - 2 - tooltip - + 47 - PRIM_BUMP_DISKS + OBJECT_SCRIPT_MEMORY + tooltip + type integer value - 10 - tooltip - + 11 - PRIM_BUMP_GRAVEL + OBJECT_SCRIPT_TIME + tooltip + type integer value - 11 - tooltip - + 12 - PRIM_BUMP_LARGETILE + OBJECT_SELECT_COUNT + tooltip + This is a flag used with llGetObjectDetails to get the number of avatars selecting any part of the object type integer value - 14 - tooltip - + 37 - PRIM_BUMP_NONE + OBJECT_SERVER_COST + tooltip + type integer value - 0 - tooltip - + 14 - PRIM_BUMP_SHINY + OBJECT_SIT_COUNT + tooltip + This is a flag used with llGetObjectDetails to get the number of avatars sitting on the object type integer value - 19 - tooltip - + 38 - PRIM_BUMP_SIDING + OBJECT_STREAMING_COST + tooltip + type integer value - 13 - tooltip - + 15 - PRIM_BUMP_STONE + OBJECT_TEMP_ATTACHED + tooltip + Returns boolean, indicating if object is a temp attachment. type integer value - 9 - tooltip - + 34 - PRIM_BUMP_STUCCO + OBJECT_TEMP_ON_REZ + tooltip + Returns boolean, detailing if temporary is enabled or disabled on the object. type integer value - 15 - tooltip - + 23 - PRIM_BUMP_SUCTION + OBJECT_TEXT + tooltip + Gets an objects hover text. type integer value - 16 - tooltip - + 44 - PRIM_BUMP_TILE + OBJECT_TEXT_ALPHA + tooltip + Gets the alpha of an objects hover text. type integer value - 8 - tooltip - + 49 - PRIM_BUMP_WEAVE + OBJECT_TEXT_COLOR + tooltip + Gets the color of an objects hover text. type integer value - 17 - tooltip - + 48 - PRIM_BUMP_WOOD + OBJECT_TOTAL_INVENTORY_COUNT + tooltip + Gets the total inventory count of the object. The script and target object must be owned by the same owner type integer value - 3 - tooltip - + 31 - PRIM_CAST_SHADOWS + OBJECT_TOTAL_SCRIPT_COUNT - deprecated - true + tooltip + type integer value - 24 - tooltip - + 10 - PRIM_COLOR + OBJECT_UNKNOWN_DETAIL + tooltip + type integer value - 18 - tooltip - + -1 - PRIM_DESC + OBJECT_VELOCITY + tooltip + Gets the object's velocity. type integer value - 28 - tooltip - + 5 - PRIM_FLEXIBLE + OPT_AVATAR + tooltip + Returned for avatars. type integer value - 21 - tooltip - + 1 - PRIM_FULLBRIGHT + OPT_CHARACTER + tooltip + Returned for pathfinding characters. type integer value - 20 - tooltip - + 2 - PRIM_GLOW + OPT_EXCLUSION_VOLUME + tooltip + Returned for exclusion volumes. type integer value - 25 - tooltip - PRIM_GLOW is used to get or set the glow status of the face. + 6 - PRIM_HOLE_CIRCLE + OPT_LEGACY_LINKSET + tooltip + Returned for movable obstacles, movable phantoms, physical, and volumedetect objects. type integer value - 0x10 - tooltip - + 0 - PRIM_HOLE_DEFAULT + OPT_MATERIAL_VOLUME + tooltip + Returned for material volumes. type integer value - 0x00 - tooltip - + 5 - PRIM_HOLE_SQUARE + OPT_OTHER + tooltip + Returned for attachments, Linden trees, and grass. type integer value - 0x20 - tooltip - + -1 - PRIM_HOLE_TRIANGLE + OPT_STATIC_OBSTACLE + tooltip + Returned for static obstacles. type integer value - 0x30 - tooltip - + 4 - PRIM_LINK_TARGET + OPT_WALKABLE + tooltip + Returned for walkable objects. type integer value - 34 - tooltip - + 3 - PRIM_MATERIAL + PARCEL_COUNT_GROUP + tooltip + type integer value - 2 - tooltip - + 2 - PRIM_MATERIAL_FLESH + PARCEL_COUNT_OTHER + tooltip + type integer value - 4 - tooltip - + 3 - PRIM_MATERIAL_GLASS + PARCEL_COUNT_OWNER + tooltip + type integer value - 2 - tooltip - + 1 - PRIM_MATERIAL_LIGHT + PARCEL_COUNT_SELECTED + tooltip + type integer value - 7 - tooltip - + 4 - PRIM_MATERIAL_METAL + PARCEL_COUNT_TEMP + tooltip + type integer value - 1 - tooltip - + 5 - PRIM_MATERIAL_PLASTIC + PARCEL_COUNT_TOTAL + tooltip + type integer value - 5 - tooltip - + 0 - PRIM_MATERIAL_RUBBER + PARCEL_DETAILS_AREA + tooltip + The parcel's area, in square meters. (5 chars.). type integer value - 6 - tooltip - + 4 - PRIM_MATERIAL_STONE + PARCEL_DETAILS_DESC + tooltip + The description of the parcel. (127 chars). type integer value - 0 - tooltip - + 1 - PRIM_MATERIAL_WOOD + PARCEL_DETAILS_FLAGS + tooltip + Flags set on the parcel type integer value - 3 - tooltip - + 12 - PRIM_MEDIA_ALT_IMAGE_ENABLE + PARCEL_DETAILS_GROUP + tooltip + The parcel group's key. (36 chars.). type integer value - 0 - tooltip - Boolean. Gets/Sets the default image state (the image that the user sees before a piece of media is active) for the chosen face. The default image is specified by Second Life's server for that media type. + 3 - PRIM_MEDIA_AUTO_LOOP + PARCEL_DETAILS_ID + tooltip + The parcel's key. (36 chars.). type integer value - 4 - tooltip - Boolean. Gets/Sets whether auto-looping is enabled. + 5 - PRIM_MEDIA_AUTO_PLAY + PARCEL_DETAILS_LANDING_LOOKAT + tooltip + Lookat vector set for teleport routing. type integer value - 5 - tooltip - Boolean. Gets/Sets whether the media auto-plays when a Resident can view it. + 10 - PRIM_MEDIA_AUTO_SCALE + PARCEL_DETAILS_LANDING_POINT + tooltip + The parcel's landing point, if any. type integer value - 6 - tooltip - Boolean. Gets/Sets whether auto-scaling is enabled. Auto-scaling forces the media to the full size of the texture. + 9 - PRIM_MEDIA_AUTO_ZOOM + PARCEL_DETAILS_NAME + tooltip + The name of the parcel. (63 chars.). type integer value - 7 - tooltip - Boolean. Gets/Sets whether clicking the media triggers auto-zoom and auto-focus on the media. + 0 - PRIM_MEDIA_CONTROLS + PARCEL_DETAILS_OWNER + tooltip + The parcel owner's key. (36 chars.). type integer value - 1 - tooltip - Integer. Gets/Sets the style of controls. Can be either PRIM_MEDIA_CONTROLS_STANDARD or PRIM_MEDIA_CONTROLS_MINI. + 2 - PRIM_MEDIA_CONTROLS_MINI + PARCEL_DETAILS_PRIM_CAPACITY + tooltip + The parcel's prim capacity. type integer value - 1 - tooltip - Mini web navigation controls; does not include an address bar. + 7 - PRIM_MEDIA_CONTROLS_STANDARD + PARCEL_DETAILS_PRIM_USED + tooltip + The number of prims used on this parcel. type integer value - 0 - tooltip - Standard web navigation controls. + 8 - PRIM_MEDIA_CURRENT_URL + PARCEL_DETAILS_SCRIPT_DANGER + tooltip + There are restrictions on this parcel that may impact script execution. type integer value - 2 - tooltip - String. Gets/Sets the current url displayed on the chosen face. Changing this URL causes navigation. 1024 characters Maximum. + 13 - PRIM_MEDIA_FIRST_CLICK_INTERACT + PARCEL_DETAILS_SEE_AVATARS + tooltip + The parcel's avatar visibility setting. (1 char.). type integer value - 8 - tooltip - Boolean. Gets/Sets whether the first click interaction is enabled. + 6 - PRIM_MEDIA_HEIGHT_PIXELS + PARCEL_DETAILS_TP_ROUTING + tooltip + Parcel's teleport routing setting. type integer value - 10 - tooltip - Integer. Gets/Sets the height of the media in pixels. + 11 - PRIM_MEDIA_HOME_URL + PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY + tooltip + type integer value - 3 - tooltip - String. Gets/Sets the home URL for the chosen face. 1024 characters maximum. + 0x08000000 - PRIM_MEDIA_MAX_HEIGHT_PIXELS + PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS + tooltip + type integer value - 2048 - tooltip - + 0x4000000 - PRIM_MEDIA_MAX_URL_LENGTH + PARCEL_FLAG_ALLOW_CREATE_OBJECTS + tooltip + type integer value - 1024 - tooltip - + 0x40 - PRIM_MEDIA_MAX_WHITELIST_COUNT + PARCEL_FLAG_ALLOW_DAMAGE + tooltip + type integer value - 64 - tooltip - + 0x20 - PRIM_MEDIA_MAX_WHITELIST_SIZE + PARCEL_FLAG_ALLOW_FLY + tooltip + type integer value - 1024 - tooltip - + 0x1 - PRIM_MEDIA_MAX_WIDTH_PIXELS + PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY + tooltip + type integer value - 2048 - tooltip - + 0x10000000 - PRIM_MEDIA_PARAM_MAX + PARCEL_FLAG_ALLOW_GROUP_SCRIPTS + tooltip + type integer value - 14 - tooltip - + 0x2000000 - PRIM_MEDIA_PERM_ANYONE + PARCEL_FLAG_ALLOW_LANDMARK + tooltip + type integer value - 4 - tooltip - + 0x8 - PRIM_MEDIA_PERM_GROUP + PARCEL_FLAG_ALLOW_SCRIPTS + tooltip + type integer value - 2 - tooltip - + 0x2 - PRIM_MEDIA_PERM_NONE + PARCEL_FLAG_ALLOW_TERRAFORM + tooltip + type integer value - 0 - tooltip - + 0x10 - PRIM_MEDIA_PERM_OWNER + PARCEL_FLAG_LOCAL_SOUND_ONLY + tooltip + type integer value - 1 - tooltip - + 0x8000 - PRIM_MEDIA_PERMS_CONTROL + PARCEL_FLAG_RESTRICT_PUSHOBJECT + tooltip + type integer value - 14 - tooltip - Integer. Gets/Sets the permissions mask that control who can see the media control bar above the object:: PRIM_MEDIA_PERM_ANYONE, PRIM_MEDIA_PERM_GROUP, PRIM_MEDIA_PERM_NONE, PRIM_MEDIA_PERM_OWNER + 0x200000 - PRIM_MEDIA_PERMS_INTERACT + PARCEL_FLAG_USE_ACCESS_GROUP + tooltip + type integer value - 13 - tooltip - Integer. Gets/Sets the permissions mask that control who can interact with the object: PRIM_MEDIA_PERM_ANYONE, PRIM_MEDIA_PERM_GROUP, PRIM_MEDIA_PERM_NONE, PRIM_MEDIA_PERM_OWNER + 0x100 - PRIM_MEDIA_WHITELIST + PARCEL_FLAG_USE_ACCESS_LIST + tooltip + type integer value - 12 - tooltip - String. Gets/Sets the white-list as a string of escaped, comma-separated URLs. This string can hold up to 64 URLs or 1024 characters, whichever comes first. + 0x200 - PRIM_MEDIA_WHITELIST_ENABLE + PARCEL_FLAG_USE_BAN_LIST + tooltip + type integer value - 11 - tooltip - Boolean. Gets/Sets whether navigation is restricted to URLs in PRIM_MEDIA_WHITELIST. + 0x400 - PRIM_MEDIA_WIDTH_PIXELS + PARCEL_FLAG_USE_LAND_PASS_LIST + tooltip + type integer value - 9 - tooltip - Integer. Gets/Sets the width of the media in pixels. + 0x800 - PRIM_NAME + PARCEL_MEDIA_COMMAND_AGENT + tooltip + type integer value - 27 - tooltip - + 7 - PRIM_NORMAL + PARCEL_MEDIA_COMMAND_AUTO_ALIGN + tooltip + type integer value - 37 - tooltip - Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians + 9 - PRIM_OMEGA + PARCEL_MEDIA_COMMAND_DESC + tooltip + Use this to get or set the parcel media description. type integer value - 32 - tooltip - + 12 - PRIM_PHANTOM + PARCEL_MEDIA_COMMAND_LOOP + tooltip + type integer value - 5 - tooltip - + 3 - PRIM_PHYSICS + PARCEL_MEDIA_COMMAND_LOOP_SET + tooltip + Used to get or set the parcel's media looping variable. type integer value - 3 - tooltip - + 13 - PRIM_PHYSICS_SHAPE_CONVEX + PARCEL_MEDIA_COMMAND_PAUSE + tooltip + type integer value - 2 - tooltip - Use the convex hull of the prim shape for physics (this is the default for mesh objects). + 1 - PRIM_PHYSICS_SHAPE_NONE + PARCEL_MEDIA_COMMAND_PLAY + tooltip + type integer value - 1 - tooltip - Ignore this prim in the physics shape. NB: This cannot be applied to the root prim. + 2 - PRIM_PHYSICS_SHAPE_PRIM + PARCEL_MEDIA_COMMAND_SIZE + tooltip + Use this to get or set the parcel media pixel resolution. type integer value - 0 - tooltip - Use the normal prim shape for physics (this is the default for all non-mesh objects). + 11 - PRIM_PHYSICS_SHAPE_TYPE + PARCEL_MEDIA_COMMAND_STOP + tooltip + type integer value - 30 - tooltip - Allows you to set the physics shape type of a prim via lsl. Permitted values are: - PRIM_PHYSICS_SHAPE_NONE, PRIM_PHYSICS_SHAPE_PRIM, PRIM_PHYSICS_SHAPE_CONVEX + 0 - PRIM_POINT_LIGHT + PARCEL_MEDIA_COMMAND_TEXTURE + tooltip + type integer value - 23 - tooltip - + 4 - PRIM_POS_LOCAL + PARCEL_MEDIA_COMMAND_TIME + tooltip + type integer value - 33 - tooltip - + 6 - PRIM_POSITION + PARCEL_MEDIA_COMMAND_TYPE + tooltip + Use this to get or set the parcel media MIME type (e.g. "text/html"). type integer value - 6 - tooltip - + 10 - PRIM_ROT_LOCAL + PARCEL_MEDIA_COMMAND_UNLOAD + tooltip + type integer value - 29 - tooltip - + 8 - PRIM_ROTATION + PARCEL_MEDIA_COMMAND_URL + tooltip + type integer value - 8 - tooltip - + 5 - PRIM_SCULPT_FLAG_INVERT + PASSIVE + tooltip + Static in-world objects. type integer value - 64 - tooltip - Render inside out (inverts the normals). + 0x4 - PRIM_SCULPT_FLAG_MIRROR + PASS_ALWAYS + tooltip + Always pass the event. type integer value - 128 - tooltip - Render an X axis mirror of the sculpty. + 1 - PRIM_SCULPT_TYPE_CYLINDER + PASS_IF_NOT_HANDLED + tooltip + Pass the event if there is no script handling the event in the prim. type integer value - 4 - tooltip - + 0 - PRIM_SCULPT_TYPE_MASK + PASS_NEVER + tooltip + Always pass the event. type integer value - 7 - tooltip - + 2 - PRIM_SCULPT_TYPE_PLANE + PATROL_PAUSE_AT_WAYPOINTS + tooltip + type integer value - 3 - tooltip - + 0 - PRIM_SCULPT_TYPE_SPHERE + PAYMENT_INFO_ON_FILE + tooltip + type integer value - 1 - tooltip - + 1 - PRIM_SCULPT_TYPE_TORUS + PAYMENT_INFO_USED + tooltip + type integer value - 2 - tooltip - + 2 - PRIM_SHINY_HIGH + PAY_DEFAULT + tooltip + type integer value - 3 - tooltip - + -2 - PRIM_SHINY_LOW + PAY_HIDE + tooltip + type integer value - 1 - tooltip - + -1 - PRIM_SHINY_MEDIUM + PERMISSION_ATTACH + tooltip + If this permission is enabled, the object can successfully call llAttachToAvatar to attach to the given avatar. type integer value - 2 - tooltip - + 0x20 - PRIM_SHINY_NONE + PERMISSION_CHANGE_JOINTS + tooltip + (not yet implemented) type integer value - 0 - tooltip - + 0x100 - PRIM_SIZE + PERMISSION_CHANGE_LINKS + tooltip + If this permission is enabled, the object can successfully call llCreateLink, llBreakLink, and llBreakAllLinks to change links to other objects. type integer value - 7 - tooltip - + 0x80 - PRIM_SLICE + PERMISSION_CHANGE_PERMISSIONS + tooltip + (not yet implemented) type integer value - 35 - tooltip - + 0x200 - PRIM_SPECULAR + PERMISSION_CONTROL_CAMERA + tooltip + type integer value - 36 - tooltip - Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color, integer glossy, integer environment + 0x800 - PRIM_TEMP_ON_REZ + PERMISSION_DEBIT + tooltip + If this permission is enabled, the object can successfully call llGiveMoney or llTransferLindenDollars to debit the owners account. type integer value - 4 - tooltip - + 0x2 - PRIM_TEXGEN + PERMISSION_OVERRIDE_ANIMATIONS + tooltip + Permission to override default animations. type integer value - 22 - tooltip - + 0x8000 - PRIM_TEXGEN_DEFAULT + PERMISSION_RELEASE_OWNERSHIP + tooltip + (not yet implemented) type integer value - 0 - tooltip - + 0x40 - PRIM_TEXGEN_PLANAR + PERMISSION_REMAP_CONTROLS + tooltip + (not yet implemented) type integer value - 1 - tooltip - + 0x8 - PRIM_TEXT + PERMISSION_RETURN_OBJECTS + tooltip + type integer value - 26 - tooltip - + 65536 - PRIM_TEXTURE + PERMISSION_SILENT_ESTATE_MANAGEMENT + tooltip + A script with this permission does not notify the object owner when it modifies estate access rules via llManageEstateAccess. type integer value - 17 - tooltip - + 0x4000 - PRIM_TYPE + PERMISSION_TAKE_CONTROLS + tooltip + If this permission enabled, the object can successfully call the llTakeControls libray call. type integer value - 9 - tooltip - + 0x4 - PRIM_TYPE_BOX + PERMISSION_TELEPORT + tooltip + type integer value - 0 - tooltip - + 0x1000 - PRIM_TYPE_CYLINDER + PERMISSION_TRACK_CAMERA + tooltip + type integer value - 1 - tooltip - + 0x400 - PRIM_TYPE_PRISM + PERMISSION_TRIGGER_ANIMATION + tooltip + If this permission is enabled, the object can successfully call llStartAnimation for the avatar that owns this. type integer value - 2 - tooltip - + 0x10 - PRIM_TYPE_RING + PERM_ALL + tooltip + type integer value - 6 - tooltip - + 0x7FFFFFFF - PRIM_TYPE_SCULPT + PERM_COPY + tooltip + type integer value - 7 - tooltip - + 0x8000 - PRIM_TYPE_SPHERE + PERM_MODIFY + tooltip + type integer value - 3 - tooltip - + 0x4000 - PRIM_TYPE_TORUS + PERM_MOVE + tooltip + type integer value - 4 - tooltip - + 0x80000 - PRIM_TYPE_TUBE + PERM_TRANSFER + tooltip + type integer value - 5 - tooltip - + 0x2000 - PROFILE_NONE + PI + tooltip + 3.14159265 - The number of radians in a semi-circle. type - integer + float value - 0 - tooltip - Disables profiling + 3.14159265 - PROFILE_SCRIPT_MEMORY + PING_PONG + tooltip + Play animation going forwards, then backwards. type integer value - 1 - tooltip - Enables memory profiling + 0x8 - PSYS_PART_BF_DEST_COLOR + PI_BY_TWO + tooltip + 1.57079633 - The number of radians in a quarter circle. type - integer + float value - 2 - tooltip - + 1.57079633 - PSYS_PART_BF_ONE + PRIM_ALLOW_UNSIT + tooltip + Prim parameter for restricting manual standing for seated avatars in an experience.\nIgnored if the avatar was not seated via a call to llSitOnLink. type integer value - 0 - tooltip - + 39 - PSYS_PART_BF_ONE_MINUS_DEST_COLOR + PRIM_ALPHA_MODE + tooltip + Prim parameter for materials using integer face, integer alpha_mode, integer alpha_cutoff.\nDefines how the alpha channel of the diffuse texture should be rendered.\nValid options for alpha_mode are PRIM_ALPHA_MODE_BLEND, _NONE, _MASK, and _EMISSIVE.\nalpha_cutoff is used only for PRIM_ALPHA_MODE_MASK. type integer value - 4 - tooltip - + 38 - PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR + PRIM_ALPHA_MODE_BLEND + tooltip + Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as alpha-blended. type integer value - 5 - tooltip - + 1 - PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA + PRIM_ALPHA_MODE_EMISSIVE + tooltip + Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as an emissivity mask. type integer value - 9 - tooltip - + 3 - PSYS_PART_BF_SOURCE_ALPHA + PRIM_ALPHA_MODE_MASK + tooltip + Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as fully opaque for alpha values above alpha_cutoff and fully transparent otherwise. type integer value - 7 - tooltip - + 2 - PSYS_PART_BF_SOURCE_COLOR + PRIM_ALPHA_MODE_NONE + tooltip + Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be ignored. type integer value - 3 - tooltip - + 0 - PSYS_PART_BF_ZERO + PRIM_BUMP_BARK + tooltip + type integer value - 1 - tooltip - + 4 - PSYS_PART_BLEND_FUNC_DEST + PRIM_BUMP_BLOBS + tooltip + type integer value - 25 - tooltip - + 12 - PSYS_PART_BLEND_FUNC_SOURCE + PRIM_BUMP_BRICKS + tooltip + type integer value - 24 - tooltip - + 5 - PSYS_PART_BOUNCE_MASK + PRIM_BUMP_BRIGHT + tooltip + type integer value - 0x4 - tooltip - Particles bounce off of a plane at the objects Z height. + 1 - PSYS_PART_EMISSIVE_MASK + PRIM_BUMP_CHECKER + tooltip + type integer value - 0x100 - tooltip - The particle glows. + 6 - PSYS_PART_END_ALPHA + PRIM_BUMP_CONCRETE + tooltip + type integer value - 4 - tooltip - A float which determines the ending alpha of the object. + 7 - PSYS_PART_END_COLOR + PRIM_BUMP_DARK + tooltip + type integer value - 3 - tooltip - A vector <r, g, b> which determines the ending color of the object. + 2 - PSYS_PART_END_GLOW + PRIM_BUMP_DISKS + tooltip + type integer value - 27 - tooltip - + 10 - PSYS_PART_END_SCALE + PRIM_BUMP_GRAVEL + tooltip + type integer value - 6 - tooltip - A vector <sx, sy, z>, which is the ending size of the particle billboard in meters (z is ignored). + 11 - PSYS_PART_FLAGS + PRIM_BUMP_LARGETILE + tooltip + type integer value - 0 - tooltip - Each particle that is emitted by the particle system is simulated based on the following flags. To use multiple flags, bitwise or (|) them together. + 14 - PSYS_PART_FOLLOW_SRC_MASK + PRIM_BUMP_NONE + tooltip + type integer value - 0x10 - tooltip - The particle position is relative to the source objects position. + 0 - PSYS_PART_FOLLOW_VELOCITY_MASK + PRIM_BUMP_SHINY + tooltip + type integer value - 0x20 - tooltip - The particle orientation is rotated so the vertical axis faces towards the particle velocity. + 19 - PSYS_PART_INTERP_COLOR_MASK + PRIM_BUMP_SIDING + tooltip + type integer value - 0x1 - tooltip - Interpolate both the color and alpha from the start value to the end value. + 13 - PSYS_PART_INTERP_SCALE_MASK + PRIM_BUMP_STONE + tooltip + type integer value - 0x2 - tooltip - Interpolate the particle scale from the start value to the end value. + 9 - PSYS_PART_MAX_AGE + PRIM_BUMP_STUCCO + tooltip + type integer value - 7 - tooltip - Age in seconds of a particle at which it dies. + 15 - PSYS_PART_RIBBON_MASK + PRIM_BUMP_SUCTION + tooltip + type integer value - 0x400 - tooltip - + 16 - PSYS_PART_START_ALPHA + PRIM_BUMP_TILE + tooltip + type integer value - 2 - tooltip - A float which determines the starting alpha of the object. + 8 - PSYS_PART_START_COLOR + PRIM_BUMP_WEAVE + tooltip + type integer value - 1 - tooltip - A vector <r.r, g.g, b.b> which determines the starting color of the object. + 17 - PSYS_PART_START_GLOW + PRIM_BUMP_WOOD + tooltip + type integer value - 26 - tooltip - + 3 - PSYS_PART_START_SCALE + PRIM_CAST_SHADOWS + deprecated + 1 + tooltip + type integer value - 5 - tooltip - A vector <sx, sy, z>, which is the starting size of the particle billboard in meters (z is ignored). + 24 - PSYS_PART_TARGET_LINEAR_MASK + PRIM_CLICK_ACTION + tooltip + type integer value - 0x80 - tooltip - + 43 - PSYS_PART_TARGET_POS_MASK + PRIM_COLLISION_SOUND + tooltip + Collision sound uuid and volume for this prim type integer value - 0x40 - tooltip - The particle heads towards the location of the target object as defined by PSYS_SRC_TARGET_KEY. + 53 - PSYS_PART_WIND_MASK + PRIM_COLOR + tooltip + type integer value - 0x8 - tooltip - Particles have their velocity damped towards the wind velocity. + 18 - PSYS_SRC_ACCEL + PRIM_DAMAGE + tooltip + Damage and damage type assigned to this prim. type integer value - 8 - tooltip - A vector <x, y, z> which is the acceleration to apply on particles. + 51 - PSYS_SRC_ANGLE_BEGIN + PRIM_DESC + tooltip + type integer value - 22 - tooltip - Area in radians specifying where particles will NOT be created (for ANGLE patterns) + 28 - PSYS_SRC_ANGLE_END + PRIM_FLEXIBLE + tooltip + type integer value - 23 - tooltip - Area in radians filled with particles (for ANGLE patterns) (if lower than PSYS_SRC_ANGLE_BEGIN, acts as PSYS_SRC_ANGLE_BEGIN itself, and PSYS_SRC_ANGLE_BEGIN acts as PSYS_SRC_ANGLE_END). + 21 - PSYS_SRC_BURST_PART_COUNT + PRIM_FULLBRIGHT + tooltip + type integer value - 15 - tooltip - How many particles to release in a burst. + 20 - PSYS_SRC_BURST_RADIUS + PRIM_GLOW + tooltip + PRIM_GLOW is used to get or set the glow status of the face. type integer value - 16 - tooltip - What distance from the center of the object to create the particles. + 25 - PSYS_SRC_BURST_RATE + PRIM_GLTF_ALPHA_MODE_BLEND + tooltip + Prim parameter setting for PRIM_GLTF_BASE_COLOR alpha mode "BLEND". type integer value - 13 - tooltip - How often to release a particle burst (float seconds). + 1 - PSYS_SRC_BURST_SPEED_MAX + PRIM_GLTF_ALPHA_MODE_MASK + tooltip + Prim parameter setting for PRIM_GLTF_BASE_COLOR alpha mode "MASK". type integer value - 18 - tooltip - Maximum speed that a particle should be moving. + 2 - PSYS_SRC_BURST_SPEED_MIN + PRIM_GLTF_ALPHA_MODE_OPAQUE + tooltip + Prim parameter setting for PRIM_GLTF_BASE_COLOR alpha mode "OPAQUE". type integer value - 17 - tooltip - Minimum speed that a particle should be moving. + 0 - PSYS_SRC_INNERANGLE + PRIM_GLTF_BASE_COLOR + tooltip + Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color, integer alpha_mode, integer alpha_cutoff, boolean double_sided.\nValid options for alpha_mode are PRIM_ALPHA_MODE_BLEND, _NONE, and _MASK.\nalpha_cutoff is used only for PRIM_ALPHA_MODE_MASK. type integer value - 10 - tooltip - Specifies the inner angle of the arc created by the PSYS_SRC_PATTERN_ANGLE or PSYS_SRC_PATTERN_ANGLE_CONE source pattern. - The area specified will NOT have particles in it. + 48 - PSYS_SRC_MAX_AGE + PRIM_GLTF_EMISSIVE + tooltip + Prim parameter for GLTF materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color type integer value - 19 - tooltip - How long this particle system should last, 0.0 means forever. + 46 - PSYS_SRC_OMEGA + PRIM_GLTF_METALLIC_ROUGHNESS + tooltip + Prim parameter for GLTF materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, float metallic_factor, float roughness_factor type integer value - 21 - tooltip - Sets the angular velocity to rotate the axis that SRC_PATTERN_ANGLE and SRC_PATTERN_ANGLE_CONE use. + 47 - PSYS_SRC_OUTERANGLE + PRIM_GLTF_NORMAL + tooltip + Prim parameter for GLTF materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians type integer value - 11 - tooltip - Specifies the outer angle of the arc created by the PSYS_SRC_PATTERN_ANGLE or PSYS_SRC_PATTERN_ANGLE_CONE source pattern. - The area between the outer and inner angle will be filled with particles. + 45 - PSYS_SRC_PATTERN + PRIM_HEALTH + tooltip + Health value for this prim type integer value - 9 - tooltip - The pattern which is used to generate particles. - Use one of the following values: PSYS_SRC_PATTERN Values. + 52 - PSYS_SRC_PATTERN_ANGLE + PRIM_HOLE_CIRCLE + tooltip + type integer value - 0x04 - tooltip - Shoot particles across a 2 dimensional area defined by the arc created from PSYS_SRC_OUTERANGLE. There will be an open area defined by PSYS_SRC_INNERANGLE within the larger arc. + 0x10 - PSYS_SRC_PATTERN_ANGLE_CONE + PRIM_HOLE_DEFAULT + tooltip + type integer value - 0x08 - tooltip - Shoot particles out in a 3 dimensional cone with an outer arc of PSYS_SRC_OUTERANGLE and an inner open area defined by PSYS_SRC_INNERANGLE. + 0x00 - PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY + PRIM_HOLE_SQUARE + tooltip + type integer value - 0x10 - tooltip - + 0x20 - PSYS_SRC_PATTERN_DROP + PRIM_HOLE_TRIANGLE + tooltip + type integer value - 0x01 - tooltip - Drop particles at the source position. + 0x30 - PSYS_SRC_PATTERN_EXPLODE + PRIM_LINK_TARGET + tooltip + type integer value - 0x02 - tooltip - Shoot particles out in all directions, using the burst parameters. + 34 - PSYS_SRC_TARGET_KEY + PRIM_MATERIAL + tooltip + type integer value - 20 - tooltip - The key of a target object to move towards if PSYS_PART_TARGET_POS_MASK is enabled. + 2 - PSYS_SRC_TEXTURE + PRIM_MATERIAL_FLESH + tooltip + type integer value - 12 - tooltip - An asset name for the texture to use for the particles. + 4 - PU_EVADE_HIDDEN + PRIM_MATERIAL_GLASS + tooltip + type integer value - 0x07 - tooltip - Triggered when an llEvade character thinks it has hidden from its pursuer. + 2 - PU_EVADE_SPOTTED + PRIM_MATERIAL_LIGHT + tooltip + type integer value - 0x08 - tooltip - Triggered when an llEvade character switches from hiding to running + 7 - PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED + PRIM_MATERIAL_METAL + tooltip + type integer value - 10 - tooltip - + 1 - PU_FAILURE_INVALID_GOAL + PRIM_MATERIAL_PLASTIC + tooltip + type integer value - 0x03 - tooltip - Goal is not on the navigation-mesh and cannot be reached. + 5 - PU_FAILURE_INVALID_START + PRIM_MATERIAL_RUBBER + tooltip + type integer value - 0x02 - tooltip - Character cannot navigate from the current location - e.g., the character is off the navmesh or too high above it. + 6 - PU_FAILURE_NO_NAVMESH + PRIM_MATERIAL_STONE + tooltip + type integer value - 0x09 - tooltip - This is a fatal error reported to a character when there is no navmesh for the region. This usually indicates a server failure and users should file a bug report and include the time and region in which they received this message. + 0 - PU_FAILURE_NO_VALID_DESTINATION + PRIM_MATERIAL_WOOD + tooltip + type integer value - 0x06 - tooltip - There is no good place for the character to go - e.g., it is patrolling and all the patrol points are now unreachable. + 3 - PU_FAILURE_OTHER + PRIM_MEDIA_ALT_IMAGE_ENABLE + tooltip + Boolean. Gets/Sets the default image state (the image that the user sees before a piece of media is active) for the chosen face. The default image is specified by Second Life's server for that media type. type integer value - 1000000 - tooltip - + 0 - PU_FAILURE_PARCEL_UNREACHABLE + PRIM_MEDIA_AUTO_LOOP + tooltip + Boolean. Gets/Sets whether auto-looping is enabled. type integer value - 11 - tooltip - + 4 - PU_FAILURE_TARGET_GONE + PRIM_MEDIA_AUTO_PLAY + tooltip + Boolean. Gets/Sets whether the media auto-plays when a Resident can view it. type integer value - 0x05 - tooltip - Target (for llPursue or llEvade) can no longer be tracked - e.g., it left the region or is an avatar that is now more than about 30m outside the region. + 5 - PU_FAILURE_UNREACHABLE + PRIM_MEDIA_AUTO_SCALE + tooltip + Boolean. Gets/Sets whether auto-scaling is enabled. Auto-scaling forces the media to the full size of the texture. type integer value - 0x04 - tooltip - Goal is no longer reachable for some reason - e.g., an obstacle blocks the path. + 6 - PU_GOAL_REACHED + PRIM_MEDIA_AUTO_ZOOM + tooltip + Boolean. Gets/Sets whether clicking the media triggers auto-zoom and auto-focus on the media. type integer value - 0x01 - tooltip - Character has reached the goal and will stop or choose a new goal (if wandering). + 7 - PU_SLOWDOWN_DISTANCE_REACHED + PRIM_MEDIA_CONTROLS + tooltip + Integer. Gets/Sets the style of controls. Can be either PRIM_MEDIA_CONTROLS_STANDARD or PRIM_MEDIA_CONTROLS_MINI. type integer value - 0x00 - tooltip - Character is near current goal. + 1 - PUBLIC_CHANNEL + PRIM_MEDIA_CONTROLS_MINI + tooltip + Mini web navigation controls; does not include an address bar. type integer value - 0 - tooltip - PUBLIC_CHANNEL is an integer constant that, when passed to llSay, llWhisper, or llShout as a channel parameter, will print text to the publicly heard chat channel. + 1 - PURSUIT_FUZZ_FACTOR + PRIM_MEDIA_CONTROLS_STANDARD + tooltip + Standard web navigation controls. type integer value - 3 - tooltip - Selects a random destination near the offset. + 0 - PURSUIT_GOAL_TOLERANCE + PRIM_MEDIA_CURRENT_URL + tooltip + String. Gets/Sets the current url displayed on the chosen face. Changing this URL causes navigation. 1024 characters Maximum. type integer value - 5 - tooltip - + 2 - PURSUIT_INTERCEPT + PRIM_MEDIA_FIRST_CLICK_INTERACT + tooltip + Boolean. Gets/Sets whether the first click interaction is enabled. type integer value - 4 - tooltip - Define whether the character attempts to predict the target's location. + 8 - PURSUIT_OFFSET + PRIM_MEDIA_HEIGHT_PIXELS + tooltip + Integer. Gets/Sets the height of the media in pixels. type integer value - 1 - tooltip - Go to a position offset from the target. + 10 - RAD_TO_DEG + PRIM_MEDIA_HOME_URL + tooltip + String. Gets/Sets the home URL for the chosen face. 1024 characters maximum. type - float + integer value - 57.2957795 - tooltip - 57.2957795 - Number of degrees per radian. You can use this number to convert radians to degrees by multiplying the radians by this number. + 3 - RC_DATA_FLAGS + PRIM_MEDIA_MAX_HEIGHT_PIXELS + tooltip + type integer value - 2 - tooltip - + 2048 - RC_DETECT_PHANTOM + PRIM_MEDIA_MAX_URL_LENGTH + tooltip + type integer value - 1 - tooltip - + 1024 - RC_GET_LINK_NUM + PRIM_MEDIA_MAX_WHITELIST_COUNT + tooltip + type integer value - 4 - tooltip - + 64 - RC_GET_NORMAL + PRIM_MEDIA_MAX_WHITELIST_SIZE + tooltip + type integer value - 1 - tooltip - + 1024 - RC_GET_ROOT_KEY + PRIM_MEDIA_MAX_WIDTH_PIXELS + tooltip + type integer value - 2 - tooltip - + 2048 - RC_MAX_HITS + PRIM_MEDIA_PARAM_MAX + tooltip + type integer value - 3 - tooltip - + 14 - RC_REJECT_AGENTS + PRIM_MEDIA_PERMS_CONTROL + tooltip + Integer. Gets/Sets the permissions mask that control who can see the media control bar above the object:: PRIM_MEDIA_PERM_ANYONE, PRIM_MEDIA_PERM_GROUP, PRIM_MEDIA_PERM_NONE, PRIM_MEDIA_PERM_OWNER type integer value - 1 - tooltip - + 14 - RC_REJECT_LAND + PRIM_MEDIA_PERMS_INTERACT + tooltip + Integer. Gets/Sets the permissions mask that control who can interact with the object: PRIM_MEDIA_PERM_ANYONE, PRIM_MEDIA_PERM_GROUP, PRIM_MEDIA_PERM_NONE, PRIM_MEDIA_PERM_OWNER type integer value - 8 - tooltip - + 13 - RC_REJECT_NONPHYSICAL + PRIM_MEDIA_PERM_ANYONE + tooltip + type integer value - 4 - tooltip - + 4 - RC_REJECT_PHYSICAL + PRIM_MEDIA_PERM_GROUP + tooltip + type integer value - 2 - tooltip - + 2 - RC_REJECT_TYPES + PRIM_MEDIA_PERM_NONE + tooltip + type integer value - 0 - tooltip - + 0 - RCERR_CAST_TIME_EXCEEDED + PRIM_MEDIA_PERM_OWNER + tooltip + type integer value - -3 - tooltip - + 1 - RCERR_SIM_PERF_LOW + PRIM_MEDIA_WHITELIST + tooltip + String. Gets/Sets the white-list as a string of escaped, comma-separated URLs. This string can hold up to 64 URLs or 1024 characters, whichever comes first. type integer value - -2 - tooltip - + 12 - RCERR_UNKNOWN + PRIM_MEDIA_WHITELIST_ENABLE + tooltip + Boolean. Gets/Sets whether navigation is restricted to URLs in PRIM_MEDIA_WHITELIST. type integer value - -1 - tooltip - + 11 - REGION_FLAG_ALLOW_DAMAGE + PRIM_MEDIA_WIDTH_PIXELS + tooltip + Integer. Gets/Sets the width of the media in pixels. type integer value - 0x1 - tooltip - + 9 - REGION_FLAG_ALLOW_DIRECT_TELEPORT + PRIM_NAME + tooltip + type integer value - 0x100000 - tooltip - + 27 - REGION_FLAG_BLOCK_FLY + PRIM_NORMAL + tooltip + Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians type integer value - 0x80000 - tooltip - + 37 - REGION_FLAG_BLOCK_FLYOVER + PRIM_OMEGA + tooltip + type integer value - 0x8000000 - tooltip - + 32 - REGION_FLAG_BLOCK_TERRAFORM + PRIM_PHANTOM + tooltip + type integer value - 0x40 - tooltip - + 5 - REGION_FLAG_DISABLE_COLLISIONS + PRIM_PHYSICS + tooltip + type integer value - 0x1000 - tooltip - + 3 - REGION_FLAG_DISABLE_PHYSICS + PRIM_PHYSICS_SHAPE_CONVEX + tooltip + Use the convex hull of the prim shape for physics (this is the default for mesh objects). type integer value - 0x4000 - tooltip - + 2 - REGION_FLAG_FIXED_SUN + PRIM_PHYSICS_SHAPE_NONE + tooltip + Ignore this prim in the physics shape. NB: This cannot be applied to the root prim. type integer value - 0x10 - tooltip - + 1 - REGION_FLAG_RESTRICT_PUSHOBJECT + PRIM_PHYSICS_SHAPE_PRIM + tooltip + Use the normal prim shape for physics (this is the default for all non-mesh objects). type integer value - 0x400000 - tooltip - + 0 - REGION_FLAG_SANDBOX + PRIM_PHYSICS_SHAPE_TYPE + tooltip + + Allows you to set the physics shape type of a prim via lsl. Permitted values are: + PRIM_PHYSICS_SHAPE_NONE, PRIM_PHYSICS_SHAPE_PRIM, PRIM_PHYSICS_SHAPE_CONVEX + type integer value - 0x100 - tooltip - + 30 - REMOTE_DATA_CHANNEL + PRIM_POINT_LIGHT + tooltip + type integer value - 1 - tooltip - + 23 - REMOTE_DATA_REPLY + PRIM_POSITION + tooltip + type integer value - 3 - tooltip - + 6 - REMOTE_DATA_REQUEST + PRIM_POS_LOCAL + tooltip + type integer value - 2 - tooltip - + 33 - REQUIRE_LINE_OF_SIGHT + PRIM_PROJECTOR + tooltip + type integer value - 2 - tooltip - Define whether the character needs a line-of-sight to give chase. + 42 - RESTITUTION + PRIM_REFLECTION_PROBE + tooltip + Allows you to configure the object as a custom-placed reflection probe, for image-based lighting (IBL). Only objects in the influence volume of the reflection probe object are affected. type integer value - 4 - tooltip - Used with llSetPhysicsMaterial to enable the density value. Must be between 0.0 and 1.0 + 44 - REVERSE + PRIM_REFLECTION_PROBE_BOX + tooltip + This is a flag option used with llGetPrimitiveParams and related functions when the parameter is PRIM_REFLECTION_PROBE. When set, the reflection probe is a box. When unset, the reflection probe is a sphere. type integer value - 0x4 - tooltip - Play animation in reverse direction. + 1 - ROTATE + PRIM_REFLECTION_PROBE_DYNAMIC + tooltip + This is a flag option used with llGetPrimitiveParams and related functions when the parameter is PRIM_REFLECTION_PROBE. When set, the reflection probe includes avatars in IBL effects. When unset, the reflection probe excludes avatars. type integer value - 0x20 - tooltip - Animate texture rotation. + 2 - SCALE + PRIM_REFLECTION_PROBE_MIRROR + tooltip + This is a flag option used with llGetPrimitiveParams and related functions when the parameter is PRIM_REFLECTION_PROBE. When set, the reflection probe acts as a mirror. type integer value - 0x40 - tooltip - Animate the texture scale. + 4 - SCRIPTED + PRIM_RENDER_MATERIAL + tooltip + type integer value - 0x8 - tooltip - Scripted in-world objects. + 49 - SIM_STAT_PCT_CHARS_STEPPED + PRIM_ROTATION + tooltip + type integer value - 0 - tooltip - Returns the % of pathfinding characters skipped each frame, averaged over the last minute.\nThe returned value corresponds to the "Characters Updated" stat in the viewer's Statistics Bar. + 8 - SMOOTH + PRIM_ROT_LOCAL + tooltip + type integer value - 0x10 - tooltip - Slide in the X direction, instead of playing separate frames. + 29 - SQRT2 + PRIM_SCRIPTED_SIT_ONLY + tooltip + Prim parameter for restricting manual sitting on this prim.\nSitting must be initiated via call to llSitOnLink. type - float + integer value - 1.41421356 - tooltip - 1.41421356 - The square root of 2. + 40 - STATUS_BLOCK_GRAB + PRIM_SCULPT_FLAG_ANIMESH + tooltip + Mesh is animated. type integer value - 0x40 - tooltip - Controls whether the object can be grabbed.\nA grab is the default action when in third person, and is available as the hand tool in build mode. This is useful for physical objects that you don't want other people to be able to trivially disturb. The default is FALSE + 32 - STATUS_BLOCK_GRAB_OBJECT + PRIM_SCULPT_FLAG_INVERT + tooltip + Render inside out (inverts the normals). type integer value - 0x400 - tooltip - Prevent click-and-drag movement on all prims in the object. + 64 - STATUS_BOUNDS_ERROR + PRIM_SCULPT_FLAG_MIRROR + tooltip + Render an X axis mirror of the sculpty. type integer value - 1002 - tooltip - Argument(s) passed to function had a bounds error. + 128 - STATUS_CAST_SHADOWS + PRIM_SCULPT_TYPE_CYLINDER + tooltip + type integer value - 0x200 - tooltip - + 4 - STATUS_DIE_AT_EDGE + PRIM_SCULPT_TYPE_MASK + tooltip + type integer value - 0x80 - tooltip - Controls whether the object is returned to the owners inventory if it wanders off the edge of the world.\nIt is useful to set this status TRUE for things like bullets or rockets. The default is TRUE + 7 - STATUS_INTERNAL_ERROR + PRIM_SCULPT_TYPE_MESH + tooltip + type integer value - 1999 - tooltip - An internal error occurred. + 5 - STATUS_MALFORMED_PARAMS + PRIM_SCULPT_TYPE_PLANE + tooltip + type integer value - 1000 - tooltip - Function was called with malformed parameters. + 3 - STATUS_NOT_FOUND + PRIM_SCULPT_TYPE_SPHERE + tooltip + type integer value - 1003 - tooltip - Object or other item was not found. + 1 - STATUS_NOT_SUPPORTED + PRIM_SCULPT_TYPE_TORUS + tooltip + type integer value - 1004 - tooltip - Feature not supported. + 2 - STATUS_OK + PRIM_SHINY_HIGH + tooltip + type integer value - 0 - tooltip - Result of function call was a success. + 3 - STATUS_PHANTOM + PRIM_SHINY_LOW + tooltip + type integer value - 0x10 - tooltip - Controls/indicates whether the object collides or not.\nSetting the value to TRUE makes the object non-colliding with all objects. It is a good idea to use this for most objects that move or rotate, but are non-physical. It is also useful for simulating volumetric lighting. The default is FALSE. + 1 - STATUS_PHYSICS + PRIM_SHINY_MEDIUM + tooltip + type integer value - 0x1 - tooltip - Controls/indicates whether the object moves physically.\nThis controls the same flag that the UI check-box for Physical controls. The default is FALSE. + 2 - STATUS_RETURN_AT_EDGE + PRIM_SHINY_NONE + tooltip + type integer value - 0x100 - tooltip - + 0 - STATUS_ROTATE_X + PRIM_SIT_FLAGS + tooltip + type integer value - 0x2 - tooltip - + 50 - STATUS_ROTATE_Y + PRIM_SIT_TARGET + tooltip + type integer value - 0x4 - tooltip - + 41 - STATUS_ROTATE_Z + PRIM_SIZE + tooltip + type integer value - 0x8 - tooltip - Controls/indicates whether the object can physically rotate around - the specific axis or not. This flag has no meaning - for non-physical objects. Set the value to FALSE - if you want to disable rotation around that axis. The - default is TRUE for a physical object. - A useful example to think about when visualizing - the effect is a sit-and-spin device. They spin around the - Z axis (up) but not around the X or Y axis. + 7 - STATUS_SANDBOX + PRIM_SLICE + tooltip + type integer value - 0x20 - tooltip - Controls/indicates whether the object can cross region boundaries - and move more than 20 meters from its creation - point. The default if FALSE. + 35 - STATUS_TYPE_MISMATCH + PRIM_SPECULAR + tooltip + Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color, integer glossy, integer environment type integer value - 1001 - tooltip - Argument(s) passed to function had a type mismatch. + 36 - STATUS_WHITELIST_FAILED + PRIM_TEMP_ON_REZ + tooltip + type integer value - 2001 - tooltip - Whitelist Failed. + 4 - STRING_TRIM + PRIM_TEXGEN + tooltip + type integer value - 0x03 - tooltip - + 22 - STRING_TRIM_HEAD + PRIM_TEXGEN_DEFAULT + tooltip + type integer value - 0x01 - tooltip - + 0 - STRING_TRIM_TAIL + PRIM_TEXGEN_PLANAR + tooltip + type integer value - 0x02 - tooltip - + 1 - TEXTURE_BLANK + PRIM_TEXT + tooltip + type - string + integer value - 5748decc-f629-461c-9a36-a35a221fe21f - tooltip - + 26 - TEXTURE_DEFAULT + PRIM_TEXTURE + tooltip + type - string + integer value - 89556747-24cb-43ed-920b-47caed15465f - tooltip - + 17 - TEXTURE_MEDIA + PRIM_TYPE + tooltip + type - string + integer value - 8b5fec65-8d8d-9dc5-cda8-8fdf2716e361 - tooltip - + 9 - TEXTURE_PLYWOOD + PRIM_TYPE_BOX + tooltip + type - string + integer value - 89556747-24cb-43ed-920b-47caed15465f - tooltip - + 0 - TEXTURE_TRANSPARENT + PRIM_TYPE_CYLINDER + tooltip + type - string + integer value - 8dcd4a48-2d37-4909-9f78-f7a9eb4ef903 - tooltip - + 1 - TOUCH_INVALID_FACE + PRIM_TYPE_PRISM + tooltip + type integer value - 0xFFFFFFFF - tooltip - + 2 - TOUCH_INVALID_TEXCOORD + PRIM_TYPE_RING + tooltip + type - vector + integer value - <-1.0, -1.0, 0.0> - tooltip - + 6 - TOUCH_INVALID_VECTOR + PRIM_TYPE_SCULPT + tooltip + type - vector + integer value - <0.0, 0.0, 0.0> - tooltip - + 7 - TRAVERSAL_TYPE + PRIM_TYPE_SPHERE + tooltip + type integer value - 7 - tooltip - One of TRAVERSAL_TYPE_FAST, TRAVERSAL_TYPE_SLOW, and TRAVERSAL_TYPE_NONE. + 3 - TRAVERSAL_TYPE_FAST + PRIM_TYPE_TORUS + tooltip + type integer value - 1 - tooltip - + 4 - TRAVERSAL_TYPE_NONE + PRIM_TYPE_TUBE + tooltip + type integer value - 2 - tooltip - + 5 - TRAVERSAL_TYPE_SLOW + PROFILE_NONE + tooltip + Disables profiling type integer value - 0 - tooltip - + 0 - TRUE + PROFILE_SCRIPT_MEMORY + tooltip + Enables memory profiling type integer value - 1 - tooltip - An integer constant for boolean comparisons. Has the value '1'. + 1 - TWO_PI + PSYS_PART_BF_DEST_COLOR + tooltip + type - float + integer value - 6.28318530 - tooltip - 6.28318530 - The radians of a circle. + 2 - TYPE_FLOAT + PSYS_PART_BF_ONE + tooltip + type integer value - 2 - tooltip - The list entry is a float. + 0 - TYPE_INTEGER + PSYS_PART_BF_ONE_MINUS_DEST_COLOR + tooltip + type integer value - 1 - tooltip - The list entry is an integer. + 4 - TYPE_INVALID + PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA + tooltip + type integer value - 0 - tooltip - The list entry is invalid. + 9 - TYPE_KEY + PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR + tooltip + type integer value - 4 - tooltip - The list entry is a key. + 5 - TYPE_ROTATION + PSYS_PART_BF_SOURCE_ALPHA + tooltip + type integer value - 6 - tooltip - The list entry is a rotation. + 7 - TYPE_STRING + PSYS_PART_BF_SOURCE_COLOR + tooltip + type integer value - 3 - tooltip - The list entry is a string. + 3 - TYPE_VECTOR + PSYS_PART_BF_ZERO + tooltip + type integer value - 5 - tooltip - The list entry is a vector. + 1 - URL_REQUEST_DENIED + PSYS_PART_BLEND_FUNC_DEST - type - string - value - URL_REQUEST_DENIED tooltip - - - URL_REQUEST_GRANTED - + type - string + integer value - URL_REQUEST_GRANTED - tooltip - + 25 - VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY + PSYS_PART_BLEND_FUNC_SOURCE + tooltip + type integer value - 32 - tooltip - A slider between minimum (0.0) and maximum (1.0) deflection of angular orientation. That is, its a simple scalar for modulating the strength of angular deflection such that the vehicles preferred axis of motion points toward its real velocity. + 24 - VEHICLE_ANGULAR_DEFLECTION_TIMESCALE + PSYS_PART_BOUNCE_MASK + tooltip + Particles bounce off of a plane at the objects Z height. type integer value - 33 - tooltip - The time-scale for exponential success of linear deflection deflection. Its another way to specify the strength of the vehicles tendency to reorient itself so that its preferred axis of motion agrees with its true velocity. + 0x4 - VEHICLE_ANGULAR_FRICTION_TIMESCALE + PSYS_PART_EMISSIVE_MASK + tooltip + The particle glows. type integer value - 17 - tooltip - A vector of timescales for exponential decay of the vehicles angular velocity about its preferred axes of motion (at, left, up). - Range = [0.07, inf) seconds for each element of the vector. + 0x100 - VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE + PSYS_PART_END_ALPHA + tooltip + A float which determines the ending alpha of the object. type integer value - 35 - tooltip - The timescale for exponential decay of the angular motors magnitude. + 4 - VEHICLE_ANGULAR_MOTOR_DIRECTION + PSYS_PART_END_COLOR + tooltip + A vector <r, g, b> which determines the ending color of the object. type integer value - 19 - tooltip - The direction and magnitude (in preferred frame) of the vehicles angular motor.The vehicle will accelerate (or decelerate if necessary) to match its velocity to its motor. + 3 - VEHICLE_ANGULAR_MOTOR_TIMESCALE + PSYS_PART_END_GLOW + tooltip + type integer value - 34 - tooltip - The timescale for exponential approach to full angular motor velocity. + 27 - VEHICLE_BANKING_EFFICIENCY + PSYS_PART_END_SCALE + tooltip + A vector <sx, sy, z>, which is the ending size of the particle billboard in meters (z is ignored). type integer value - 38 - tooltip - A slider between anti (-1.0), none (0.0), and maxmum (1.0) banking strength. + 6 - VEHICLE_BANKING_MIX + PSYS_PART_FLAGS + tooltip + Each particle that is emitted by the particle system is simulated based on the following flags. To use multiple flags, bitwise or (|) them together. type integer value - 39 - tooltip - A slider between static (0.0) and dynamic (1.0) banking. "Static" means the banking scales only with the angle of roll, whereas "dynamic" is a term that also scales with the vehicles linear speed. + 0 - VEHICLE_BANKING_TIMESCALE + PSYS_PART_FOLLOW_SRC_MASK + tooltip + The particle position is relative to the source objects position. type integer value - 40 - tooltip - The timescale for banking to exponentially approach its maximum effect. This is another way to scale the strength of the banking effect, however it affects the term that is proportional to the difference between what the banking behavior is trying to do, and what the vehicle is actually doing. + 0x10 - VEHICLE_BUOYANCY + PSYS_PART_FOLLOW_VELOCITY_MASK + tooltip + The particle orientation is rotated so the vertical axis faces towards the particle velocity. type integer value - 27 - tooltip - A slider between minimum (0.0) and maximum anti-gravity (1.0). + 0x20 - VEHICLE_FLAG_CAMERA_DECOUPLED + PSYS_PART_INTERP_COLOR_MASK + tooltip + Interpolate both the color and alpha from the start value to the end value. type integer value - 0x200 - tooltip - + 0x1 - VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT + PSYS_PART_INTERP_SCALE_MASK + tooltip + Interpolate the particle scale from the start value to the end value. type integer value - 0x10 - tooltip - Hover at global height. + 0x2 - VEHICLE_FLAG_HOVER_TERRAIN_ONLY + PSYS_PART_MAX_AGE + tooltip + Age in seconds of a particle at which it dies. type integer value - 0x8 - tooltip - Ignore water height when hovering. + 7 - VEHICLE_FLAG_HOVER_UP_ONLY + PSYS_PART_RIBBON_MASK + tooltip + type integer value - 0x20 - tooltip - Hover does not push down. Use this flag for hovering vehicles that should be able to jump above their hover height. + 0x400 - VEHICLE_FLAG_HOVER_WATER_ONLY + PSYS_PART_START_ALPHA + tooltip + A float which determines the starting alpha of the object. type integer value - 0x4 - tooltip - Ignore terrain height when hovering. + 2 - VEHICLE_FLAG_LIMIT_MOTOR_UP + PSYS_PART_START_COLOR + tooltip + A vector <r.r, g.g, b.b> which determines the starting color of the object. type integer value - 0x40 - tooltip - Prevents ground vehicles from motoring into the sky. + 1 - VEHICLE_FLAG_LIMIT_ROLL_ONLY + PSYS_PART_START_GLOW + tooltip + type integer value - 0x2 - tooltip - For vehicles with vertical attractor that want to be able to climb/dive, for instance, aeroplanes that want to use the banking feature. + 26 - VEHICLE_FLAG_MOUSELOOK_BANK + PSYS_PART_START_SCALE + tooltip + A vector <sx, sy, z>, which is the starting size of the particle billboard in meters (z is ignored). type integer value - 0x100 - tooltip - + 5 - VEHICLE_FLAG_MOUSELOOK_STEER + PSYS_PART_TARGET_LINEAR_MASK + tooltip + type integer value 0x80 - tooltip - - VEHICLE_FLAG_NO_DEFLECTION_UP + PSYS_PART_TARGET_POS_MASK + tooltip + The particle heads towards the location of the target object as defined by PSYS_SRC_TARGET_KEY. type integer value - 0x1 - tooltip - This flag prevents linear deflection parallel to world z-axis. This is useful for preventing ground vehicles with large linear deflection, like bumper cars, from climbing their linear deflection into the sky. + 0x40 - VEHICLE_FLAG_NO_FLY_UP + PSYS_PART_WIND_MASK - deprecated - true + tooltip + Particles have their velocity damped towards the wind velocity. type integer value - 0x1 - tooltip - Old, changed to VEHICLE_FLAG_NO_DEFLECTION_UP + 0x8 - VEHICLE_HOVER_EFFICIENCY + PSYS_SRC_ACCEL + tooltip + A vector <x, y, z> which is the acceleration to apply on particles. type integer value - 25 - tooltip - A slider between minimum (0.0 = bouncy) and maximum (1.0 = fast as possible) damped motion of the hover behavior. + 8 - VEHICLE_HOVER_HEIGHT + PSYS_SRC_ANGLE_BEGIN + tooltip + Area in radians specifying where particles will NOT be created (for ANGLE patterns) type integer value - 24 - tooltip - The height (above the terrain or water, or global) at which the vehicle will try to hover. + 22 - VEHICLE_HOVER_TIMESCALE + PSYS_SRC_ANGLE_END + tooltip + Area in radians filled with particles (for ANGLE patterns) (if lower than PSYS_SRC_ANGLE_BEGIN, acts as PSYS_SRC_ANGLE_BEGIN itself, and PSYS_SRC_ANGLE_BEGIN acts as PSYS_SRC_ANGLE_END). type integer value - 26 - tooltip - Period of time (in seconds) for the vehicle to achieve its hover height. + 23 - VEHICLE_LINEAR_DEFLECTION_EFFICIENCY + PSYS_SRC_BURST_PART_COUNT + tooltip + How many particles to release in a burst. type integer value - 28 - tooltip - A slider between minimum (0.0) and maximum (1.0) deflection of linear velocity. That is, its a simple scalar for modulating the strength of linear deflection. + 15 - VEHICLE_LINEAR_DEFLECTION_TIMESCALE + PSYS_SRC_BURST_RADIUS + tooltip + What distance from the center of the object to create the particles. type integer value - 29 - tooltip - The timescale for exponential success of linear deflection deflection. It is another way to specify how much time it takes for the vehicles linear velocity to be redirected to its preferred axis of motion. + 16 - VEHICLE_LINEAR_FRICTION_TIMESCALE + PSYS_SRC_BURST_RATE + tooltip + How often to release a particle burst (float seconds). type integer value - 16 - tooltip - A vector of timescales for exponential decay of the vehicles linear velocity along its preferred axes of motion (at, left, up). - Range = [0.07, inf) seconds for each element of the vector. + 13 - VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE + PSYS_SRC_BURST_SPEED_MAX + tooltip + Maximum speed that a particle should be moving. type integer value - 31 - tooltip - The timescale for exponential decay of the linear motors magnitude. + 18 - VEHICLE_LINEAR_MOTOR_DIRECTION + PSYS_SRC_BURST_SPEED_MIN + tooltip + Minimum speed that a particle should be moving. type integer value - 18 - tooltip - The direction and magnitude (in preferred frame) of the vehicles linear motor. The vehicle will accelerate (or decelerate if necessary) to match its velocity to its motor. - Range of magnitude = [0, 30] meters/second. + 17 - VEHICLE_LINEAR_MOTOR_OFFSET + PSYS_SRC_INNERANGLE + tooltip + + Specifies the inner angle of the arc created by the PSYS_SRC_PATTERN_ANGLE or PSYS_SRC_PATTERN_ANGLE_CONE source pattern. + The area specified will NOT have particles in it. + type integer value - 20 - tooltip - + 10 - VEHICLE_LINEAR_MOTOR_TIMESCALE + PSYS_SRC_MAX_AGE + tooltip + How long this particle system should last, 0.0 means forever. type integer value - 30 - tooltip - The timescale for exponential approach to full linear motor velocity. + 19 - VEHICLE_REFERENCE_FRAME + PSYS_SRC_OMEGA + tooltip + Sets the angular velocity to rotate the axis that SRC_PATTERN_ANGLE and SRC_PATTERN_ANGLE_CONE use. type integer value - 44 - tooltip - A rotation of the vehicles preferred axes of motion and orientation (at, left, up) with respect to the vehicles local frame (x, y, z). + 21 - VEHICLE_TYPE_AIRPLANE + PSYS_SRC_OUTERANGLE + tooltip + + Specifies the outer angle of the arc created by the PSYS_SRC_PATTERN_ANGLE or PSYS_SRC_PATTERN_ANGLE_CONE source pattern. + The area between the outer and inner angle will be filled with particles. + type integer value - 4 - tooltip - Uses linear deflection for lift, no hover, and banking to turn.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_AIRPLANE + 11 - VEHICLE_TYPE_BALLOON + PSYS_SRC_PATTERN + tooltip + + The pattern which is used to generate particles. + Use one of the following values: PSYS_SRC_PATTERN Values. + type integer value - 5 - tooltip - Hover, and friction, but no deflection.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_BALLOON + 9 - VEHICLE_TYPE_BOAT + PSYS_SRC_PATTERN_ANGLE + tooltip + Shoot particles across a 2 dimensional area defined by the arc created from PSYS_SRC_OUTERANGLE. There will be an open area defined by PSYS_SRC_INNERANGLE within the larger arc. type integer value - 3 - tooltip - Hovers over water with lots of friction and some anglar deflection.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_BOAT + 0x04 - VEHICLE_TYPE_CAR + PSYS_SRC_PATTERN_ANGLE_CONE + tooltip + Shoot particles out in a 3 dimensional cone with an outer arc of PSYS_SRC_OUTERANGLE and an inner open area defined by PSYS_SRC_INNERANGLE. type integer value - 2 - tooltip - Another vehicle that bounces along the ground but needs the motors to be driven from external controls or timer events.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_CAR + 0x08 - VEHICLE_TYPE_NONE + PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY + tooltip + type integer value - 0 - tooltip - + 0x10 - VEHICLE_TYPE_SLED + PSYS_SRC_PATTERN_DROP + tooltip + Drop particles at the source position. type integer value - 1 - tooltip - Simple vehicle that bumps along the ground, and likes to move along its local x-axis.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_SLED + 0x01 - VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY + PSYS_SRC_PATTERN_EXPLODE + tooltip + Shoot particles out in all directions, using the burst parameters. type integer value - 36 - tooltip - A slider between minimum (0.0 = wobbly) and maximum (1.0 = firm as possible) stability of the vehicle to keep itself upright. + 0x02 - VEHICLE_VERTICAL_ATTRACTION_TIMESCALE + PSYS_SRC_TARGET_KEY + tooltip + The key of a target object to move towards if PSYS_PART_TARGET_POS_MASK is enabled. type integer value - 37 - tooltip - The period of wobble, or timescale for exponential approach, of the vehicle to rotate such that its preferred "up" axis is oriented along the worlds "up" axis. + 20 - VERTICAL + PSYS_SRC_TEXTURE + tooltip + An asset name for the texture to use for the particles. type integer value - 0 - tooltip - + 12 - WANDER_PAUSE_AT_WAYPOINTS + PUBLIC_CHANNEL + tooltip + PUBLIC_CHANNEL is an integer constant that, when passed to llSay, llWhisper, or llShout as a channel parameter, will print text to the publicly heard chat channel. type integer value - 0 - tooltip - + 0 - XP_ERROR_EXPERIENCES_DISABLED + PURSUIT_FUZZ_FACTOR + tooltip + Selects a random destination near the offset. type integer value - 2 - tooltip - The region currently has experiences disabled. + 3 - XP_ERROR_EXPERIENCE_DISABLED + PURSUIT_GOAL_TOLERANCE + tooltip + type integer value - 8 - tooltip - The experience owner has temporarily disabled the experience. + 5 - XP_ERROR_EXPERIENCE_SUSPENDED + PURSUIT_INTERCEPT + tooltip + Define whether the character attempts to predict the target's location. type integer value - 9 - tooltip - The experience has been suspended by Linden Customer Support. + 4 - XP_ERROR_INVALID_EXPERIENCE + PURSUIT_OFFSET + tooltip + Go to a position offset from the target. type integer value - 7 - tooltip - The script is associated with an experience that no longer exists. + 1 - XP_ERROR_INVALID_PARAMETERS + PU_EVADE_HIDDEN + tooltip + Triggered when an llEvade character thinks it has hidden from its pursuer. type integer value - 3 + 0x07 + + PU_EVADE_SPOTTED + tooltip - One of the string arguments was too big to fit in the key-value store. + Triggered when an llEvade character switches from hiding to running + type + integer + value + 0x08 - XP_ERROR_KEY_NOT_FOUND + PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED + tooltip + type integer value - 14 + 10 + + PU_FAILURE_INVALID_GOAL + tooltip - The requested key does not exist. + Goal is not on the navigation-mesh and cannot be reached. + type + integer + value + 0x03 - XP_ERROR_MATURITY_EXCEEDED + PU_FAILURE_INVALID_START + tooltip + Character cannot navigate from the current location - e.g., the character is off the navmesh or too high above it. type integer value - 16 + 0x02 + + PU_FAILURE_NO_NAVMESH + tooltip - The content rating of the experience exceeds that of the region. + This is a fatal error reported to a character when there is no navmesh for the region. This usually indicates a server failure and users should file a bug report and include the time and region in which they received this message. + type + integer + value + 0x09 - XP_ERROR_NONE + PU_FAILURE_NO_VALID_DESTINATION + tooltip + There is no good place for the character to go - e.g., it is patrolling and all the patrol points are now unreachable. type integer value - 0 + 0x06 + + PU_FAILURE_OTHER + tooltip - No error was detected. + + type + integer + value + 1000000 - XP_ERROR_NOT_FOUND + PU_FAILURE_PARCEL_UNREACHABLE + tooltip + type integer value - 6 + 11 + + PU_FAILURE_TARGET_GONE + tooltip - The sim was unable to verify the validity of the experience. Retrying after a short wait is advised. + Target (for llPursue or llEvade) can no longer be tracked - e.g., it left the region or is an avatar that is now more than about 30m outside the region. + type + integer + value + 0x05 - XP_ERROR_NOT_PERMITTED + PU_FAILURE_UNREACHABLE + tooltip + Goal is no longer reachable for some reason - e.g., an obstacle blocks the path. type integer value - 4 + 0x04 + + PU_GOAL_REACHED + tooltip - This experience is not allowed to run by the requested agent. + Character has reached the goal and will stop or choose a new goal (if wandering). + type + integer + value + 0x01 - XP_ERROR_NOT_PERMITTED_LAND + PU_SLOWDOWN_DISTANCE_REACHED + tooltip + Character is near current goal. type integer value - 17 + 0x00 + + RAD_TO_DEG + tooltip - This experience is not allowed to run on the current region. + 57.2957795 - Number of degrees per radian. You can use this number to convert radians to degrees by multiplying the radians by this number. + type + float + value + 57.2957795 - XP_ERROR_NO_EXPERIENCE + RCERR_CAST_TIME_EXCEEDED + tooltip + type integer value - 5 + -3 + + RCERR_SIM_PERF_LOW + tooltip - This script is not associated with an experience. + + type + integer + value + -2 - XP_ERROR_QUOTA_EXCEEDED + RCERR_UNKNOWN + tooltip + type integer value - 11 + -1 + + RC_DATA_FLAGS + tooltip - An attempted write data to the key-value store failed due to the data quota being met. + + type + integer + value + 2 - XP_ERROR_RETRY_UPDATE + RC_DETECT_PHANTOM + tooltip + type integer value - 15 + 1 + + RC_GET_LINK_NUM + tooltip - A checked update failed due to an out of date request. + + type + integer + value + 4 - XP_ERROR_STORAGE_EXCEPTION + RC_GET_NORMAL + tooltip + type integer value - 13 + 1 + + RC_GET_ROOT_KEY + tooltip - Unable to communicate with the key-value store. + + type + integer + value + 2 - XP_ERROR_STORE_DISABLED + RC_MAX_HITS + tooltip + type integer value - 12 + 3 + + RC_REJECT_AGENTS + tooltip - The key-value store is currently disabled on this region. + + type + integer + value + 1 - XP_ERROR_THROTTLED + RC_REJECT_LAND + tooltip + type integer value - 1 + 8 + + RC_REJECT_NONPHYSICAL + tooltip - The call failed due to too many recent calls. + + type + integer + value + 4 - XP_ERROR_UNKNOWN_ERROR + RC_REJECT_PHYSICAL + tooltip + type integer value - 10 + 2 + + RC_REJECT_TYPES + tooltip - Other unknown error. + + type + integer + value + 0 - ZERO_ROTATION + REGION_FLAG_ALLOW_DAMAGE + tooltip + type - rotation + integer value - <0.0, 0.0, 0.0, 1.0> + 0x1 + + REGION_FLAG_ALLOW_DIRECT_TELEPORT + tooltip - + + type + integer + value + 0x100000 - ZERO_VECTOR + REGION_FLAG_BLOCK_FLY + tooltip + type - vector + integer value - <0.0, 0.0, 0.0> + 0x80000 + + REGION_FLAG_BLOCK_FLYOVER + tooltip - + + type + integer + value + 0x8000000 - default + REGION_FLAG_BLOCK_TERRAFORM tooltip - All scripts must have a default state, which is the first state entered when the script starts.\nIf another state is defined before the default state, the compiler will report a syntax error. + + type + integer + value + 0x40 - - events - - at_rot_target + REGION_FLAG_DISABLE_COLLISIONS - arguments - + tooltip + + type + integer + value + 0x1000 + + REGION_FLAG_DISABLE_PHYSICS + + tooltip + + type + integer + value + 0x4000 + + REGION_FLAG_FIXED_SUN + + tooltip + + type + integer + value + 0x10 + + REGION_FLAG_RESTRICT_PUSHOBJECT + + tooltip + + type + integer + value + 0x400000 + + REGION_FLAG_SANDBOX + + tooltip + + type + integer + value + 0x100 + + REMOTE_DATA_CHANNEL + + tooltip + + type + integer + value + 1 + + REMOTE_DATA_REPLY + + tooltip + + type + integer + value + 3 + + REMOTE_DATA_REQUEST + + tooltip + + type + integer + value + 2 + + REQUIRE_LINE_OF_SIGHT + + tooltip + Define whether the character needs a line-of-sight to give chase. + type + integer + value + 2 + + RESTITUTION + + tooltip + Used with llSetPhysicsMaterial to enable the density value. Must be between 0.0 and 1.0 + type + integer + value + 4 + + REVERSE + + tooltip + Play animation in reverse direction. + type + integer + value + 0x4 + + REZ_ACCEL + + tooltip + Acceleration forced applied to the rezzed object. [vector force, integer rel] + type + integer + value + 5 + + REZ_DAMAGE + + tooltip + Damage applied by the object when it collides with an agent. [float damage] + type + integer + value + 8 + + REZ_DAMAGE_TYPE + + tooltip + Set the damage type applied when this object collides. + type + integer + value + 12 + + REZ_FLAGS + + tooltip + Rez flags to set on the newly rezzed object. [integer flags] + type + integer + value + 1 + + REZ_FLAG_BLOCK_GRAB_OBJECT + + tooltip + Prevent grabbing the object. + type + integer + value + 0x0080 + + REZ_FLAG_DIE_ON_COLLIDE + + tooltip + Object will die after its first collision. + type + integer + value + 0x0008 + + REZ_FLAG_DIE_ON_NOENTRY + + tooltip + Object will die if it attempts to enter a parcel that it can not. + type + integer + value + 0x0010 + + REZ_FLAG_NO_COLLIDE_FAMILY + + tooltip + Object will not trigger collision events with other objects created by the same rezzer. + type + integer + value + 0x0040 + + REZ_FLAG_NO_COLLIDE_OWNER + + tooltip + Object will not trigger collision events with its owner. + type + integer + value + 0x0020 + + REZ_FLAG_PHANTOM + + tooltip + Make the object phantom on rez. + type + integer + value + 0x0004 + + REZ_FLAG_PHYSICAL + + tooltip + Make the object physical on rez. + type + integer + value + 0x0002 + + REZ_FLAG_TEMP + + tooltip + Flag the object as temp on rez. + type + integer + value + 0x0001 + + REZ_LOCK_AXES + + tooltip + Prevent the object from rotating around some axes. [vector locks] + type + integer + value + 11 + + REZ_OMEGA + + tooltip + Omega applied to the rezzed object. [vector axis, integer rel, float spin, float gain] + type + integer + value + 7 + + REZ_PARAM + + tooltip + Integer value to pass to the object as its rez parameter. [integer param] + type + integer + value + 0 + + REZ_PARAM_STRING + + tooltip + A string value to pass to the object as its rez parameter. [string param] + type + integer + value + 13 + + REZ_POS + + tooltip + Position at which to rez the new object. [vector position, integer rel, integer atroot] + type + integer + value + 2 + + REZ_ROT + + tooltip + Rotation applied to newly rezzed object. [rotation rot, integer rel] + type + integer + value + 3 + + REZ_SOUND + + tooltip + Sound attached to the rezzed object. [string name, float volume, integer loop] + type + integer + value + 9 + + REZ_SOUND_COLLIDE + + tooltip + Sound played by the object on a collision. [string name, float volume] + type + integer + value + 10 + + REZ_VEL + + tooltip + Initial velocity of rezzed object. [vector vel, integer rel, integer inherit] + type + integer + value + 4 + + ROTATE + + tooltip + Animate texture rotation. + type + integer + value + 0x20 + + SCALE + + tooltip + Animate the texture scale. + type + integer + value + 0x40 + + SCRIPTED + + tooltip + Scripted in-world objects. + type + integer + value + 0x8 + + SIM_STAT_ACTIVE_SCRIPT_COUNT + + tooltip + Number of active scripts. + type + integer + value + 12 + + SIM_STAT_AGENT_COUNT + + tooltip + Number of agents in region. + type + integer + value + 10 + + SIM_STAT_AGENT_MS + + tooltip + Time spent in 'agent' segment of simulation frame. + type + integer + value + 7 + + SIM_STAT_AGENT_UPDATES + + tooltip + Agent updates per second. + type + integer + value + 2 + + SIM_STAT_AI_MS + + tooltip + Time spent on AI step. + type + integer + value + 26 + + SIM_STAT_ASSET_DOWNLOADS + + tooltip + Pending asset download count. + type + integer + value + 15 + + SIM_STAT_ASSET_UPLOADS + + tooltip + Pending asset upload count. + type + integer + value + 16 + + SIM_STAT_CHILD_AGENT_COUNT + + tooltip + Number of child agents in region. + type + integer + value + 11 + + SIM_STAT_FRAME_MS + + tooltip + Total frame time. + type + integer + value + 3 + + SIM_STAT_IMAGE_MS + + tooltip + Time spent in 'image' segment of simulation frame. + type + integer + value + 8 + + SIM_STAT_IO_PUMP_MS + + tooltip + Pump IO time. + type + integer + value + 24 + + SIM_STAT_NET_MS + + tooltip + Time spent in 'network' segment of simulation frame. + type + integer + value + 4 + + SIM_STAT_OTHER_MS + + tooltip + Time spent in 'other' segment of simulation frame. + type + integer + value + 5 + + SIM_STAT_PACKETS_IN + + tooltip + Packets in per second. + type + integer + value + 13 + + SIM_STAT_PACKETS_OUT + + tooltip + Packets out per second. + type + integer + value + 14 + + SIM_STAT_PCT_CHARS_STEPPED + + tooltip + Returns the % of pathfinding characters skipped each frame, averaged over the last minute.\nThe returned value corresponds to the "Characters Updated" stat in the viewer's Statistics Bar. + type + integer + value + 0 + + SIM_STAT_PHYSICS_FPS + + tooltip + Physics simulation FPS. + type + integer + value + 1 + + SIM_STAT_PHYSICS_MS + + tooltip + Time spent in 'physics' segment of simulation frame. + type + integer + value + 6 + + SIM_STAT_PHYSICS_OTHER_MS + + tooltip + Physics other time. + type + integer + value + 20 + + SIM_STAT_PHYSICS_SHAPE_MS + + tooltip + Physics shape update time. + type + integer + value + 19 + + SIM_STAT_PHYSICS_STEP_MS + + tooltip + Physics step time. + type + integer + value + 18 + + SIM_STAT_SCRIPT_EPS + + tooltip + Script events per second. + type + integer + value + 21 + + SIM_STAT_SCRIPT_MS + + tooltip + Time spent in 'script' segment of simulation frame. + type + integer + value + 9 + + SIM_STAT_SCRIPT_RUN_PCT + + tooltip + Percent of scripts run during frame. + type + integer + value + 25 + + SIM_STAT_SLEEP_MS + + tooltip + Time spent sleeping. + type + integer + value + 23 + + SIM_STAT_SPARE_MS + + tooltip + Spare time left after frame. + type + integer + value + 22 + + SIM_STAT_UNACKED_BYTES + + tooltip + Total unacknowledged bytes. + type + integer + value + 17 + + SIT_FLAG_ALLOW_UNSIT + + tooltip + The prim allows a seated avatar to stand up. + type + integer + value + 0x0002 + + SIT_FLAG_NO_COLLIDE + + tooltip + The seated avatar's hit box is disabled when seated on this prim. + type + integer + value + 0x0010 + + SIT_FLAG_NO_DAMAGE + + tooltip + Damage will not be forwarded to an avatar seated on this prim. + type + integer + value + 0x0020 + + SIT_FLAG_SCRIPTED_ONLY + + tooltip + An avatar may not manually sit on this prim. + type + integer + value + 0x0004 + + SIT_FLAG_SIT_TARGET + + tooltip + The prim has an explicitly set sit target. + type + integer + value + 0x0001 + + SIT_INVALID_AGENT + + tooltip + Avatar ID did not specify a valid avatar. + type + integer + value + -4 + + SIT_INVALID_LINK + + tooltip + Link ID did not specify a valid prim in the linkset or resolved to multiple prims. + type + integer + value + -5 + + SIT_INVALID_OBJECT + + tooltip + Attempt to force an avatar to sit on an attachment or other invalid target. + type + integer + value + -7 + + SIT_NOT_EXPERIENCE + + tooltip + Attempt to force an avatar to sit outside an experience. + type + integer + value + -1 + + SIT_NO_ACCESS + + tooltip + Avatar does not have access to the parcel containing the target linkset of the forced sit. + type + integer + value + -6 + + SIT_NO_EXPERIENCE_PERMISSION + + tooltip + Avatar has not granted permission to force sits. + type + integer + value + -2 + + SIT_NO_SIT_TARGET + + tooltip + No available sit target in linkset for forced sit. + type + integer + value + -3 + + SKY_AMBIENT + + tooltip + The ambient color of the environment + type + integer + value + 0 + + SKY_BLUE + + tooltip + Blue settings for environment + type + integer + value + 22 + + SKY_CLOUDS + + tooltip + Settings controlling cloud density and configuration + type + integer + value + 2 + + SKY_CLOUD_TEXTURE + + tooltip + Texture ID used by clouds + type + integer + value + 19 + + SKY_DOME + + tooltip + Sky dome information. + type + integer + value + 4 + + SKY_GAMMA + + tooltip + The gamma value applied to the scene. + type + integer + value + 5 + + SKY_GLOW + + tooltip + Glow color applied to the sun and moon. + type + integer + value + 6 + + SKY_HAZE + + tooltip + Haze settings for environment + type + integer + value + 23 + + SKY_LIGHT + + tooltip + Miscellaneous lighting values. + type + integer + value + 8 + + SKY_MOON + + tooltip + Environmental moon details. + type + integer + value + 9 + + SKY_MOON_TEXTURE + + tooltip + Environmental moon texture. + type + integer + value + 20 + + SKY_PLANET + + tooltip + Planet information used in rendering the sky. + type + integer + value + 10 + + SKY_REFLECTION_PROBE_AMBIANCE + + tooltip + Settings the ambience of the reflection probe. + type + integer + value + 24 + + SKY_REFRACTION + + tooltip + Sky refraction parameters for rainbows and optical effects. + type + integer + value + 11 + + SKY_STAR_BRIGHTNESS + + tooltip + Brightness value for the stars. + type + integer + value + 13 + + SKY_SUN + + tooltip + Detailed sun information + type + integer + value + 14 + + SKY_SUN_TEXTURE + + tooltip + Environmental sun texture + type + integer + value + 21 + + SKY_TEXTURE_DEFAULTS + + tooltip + Is the environment using the default textures. + type + integer + value + 1 + + SKY_TRACKS + + tooltip + Track elevations for this region. + type + integer + value + 15 + + SMOOTH + + tooltip + Slide in the X direction, instead of playing separate frames. + type + integer + value + 0x10 + + SOUND_LOOP + + tooltip + Sound will loop until stopped. + type + integer + value + 0x01 + + SOUND_PLAY + + tooltip + Sound will play normally. + type + integer + value + 0x00 + + SOUND_SYNC + + tooltip + Sound will be synchronized with the nearest master. + type + integer + value + 0x04 + + SOUND_TRIGGER + + tooltip + Sound will be triggered at the prim's location and not attached. + type + integer + value + 0x02 + + SQRT2 + + tooltip + 1.41421356 - The square root of 2. + type + float + value + 1.41421356 + + STATUS_BLOCK_GRAB + + tooltip + Controls whether the object can be grabbed.\nA grab is the default action when in third person, and is available as the hand tool in build mode. This is useful for physical objects that you don't want other people to be able to trivially disturb. The default is FALSE + type + integer + value + 0x40 + + STATUS_BLOCK_GRAB_OBJECT + + tooltip + Prevent click-and-drag movement on all prims in the object. + type + integer + value + 0x400 + + STATUS_BOUNDS_ERROR + + tooltip + Argument(s) passed to function had a bounds error. + type + integer + value + 1002 + + STATUS_CAST_SHADOWS + + tooltip + + type + integer + value + 0x200 + + STATUS_DIE_AT_EDGE + + tooltip + Controls whether the object is returned to the owners inventory if it wanders off the edge of the world.\nIt is useful to set this status TRUE for things like bullets or rockets. The default is TRUE + type + integer + value + 0x80 + + STATUS_DIE_AT_NO_ENTRY + + tooltip + Controls whether the object dies if it attempts to enter a parcel that does not allow object entry or does not have enough capacity.\nIt is useful to set this status TRUE for things like bullets or rockets. The default is FALSE + type + integer + value + 0x800 + + STATUS_INTERNAL_ERROR + + tooltip + An internal error occurred. + type + integer + value + 1999 + + STATUS_MALFORMED_PARAMS + + tooltip + Function was called with malformed parameters. + type + integer + value + 1000 + + STATUS_NOT_FOUND + + tooltip + Object or other item was not found. + type + integer + value + 1003 + + STATUS_NOT_SUPPORTED + + tooltip + Feature not supported. + type + integer + value + 1004 + + STATUS_OK + + tooltip + Result of function call was a success. + type + integer + value + 0 + + STATUS_PHANTOM + + tooltip + Controls/indicates whether the object collides or not.\nSetting the value to TRUE makes the object non-colliding with all objects. It is a good idea to use this for most objects that move or rotate, but are non-physical. It is also useful for simulating volumetric lighting. The default is FALSE. + type + integer + value + 0x10 + + STATUS_PHYSICS + + tooltip + Controls/indicates whether the object moves physically.\nThis controls the same flag that the UI check-box for Physical controls. The default is FALSE. + type + integer + value + 0x1 + + STATUS_RETURN_AT_EDGE + + tooltip + + type + integer + value + 0x100 + + STATUS_ROTATE_X + + tooltip + + type + integer + value + 0x2 + + STATUS_ROTATE_Y + + tooltip + + type + integer + value + 0x4 + + STATUS_ROTATE_Z + + tooltip + + Controls/indicates whether the object can physically rotate around + the specific axis or not. This flag has no meaning + for non-physical objects. Set the value to FALSE + if you want to disable rotation around that axis. The + default is TRUE for a physical object. + A useful example to think about when visualizing + the effect is a sit-and-spin device. They spin around the + Z axis (up) but not around the X or Y axis. + + type + integer + value + 0x8 + + STATUS_SANDBOX + + tooltip + + Controls/indicates whether the object can cross region boundaries + and move more than 20 meters from its creation + point. The default if FALSE. + + type + integer + value + 0x20 + + STATUS_TYPE_MISMATCH + + tooltip + Argument(s) passed to function had a type mismatch. + type + integer + value + 1001 + + STATUS_WHITELIST_FAILED + + tooltip + Whitelist Failed. + type + integer + value + 2001 + + STRING_TRIM + + tooltip + + type + integer + value + 0x03 + + STRING_TRIM_HEAD + + tooltip + + type + integer + value + 0x01 + + STRING_TRIM_TAIL + + tooltip + + type + integer + value + 0x02 + + TARGETED_EMAIL_OBJECT_OWNER + + tooltip + Send email to the owner of the object + type + integer + value + 0x02 + + TARGETED_EMAIL_ROOT_CREATOR + + tooltip + Send email to the creator of the root object + type + integer + value + 0x01 + + TERRAIN_DETAIL_1 + + tooltip + + type + integer + value + 0 + + TERRAIN_DETAIL_2 + + tooltip + + type + integer + value + 1 + + TERRAIN_DETAIL_3 + + tooltip + + type + integer + value + 2 + + TERRAIN_DETAIL_4 + + tooltip + + type + integer + value + 3 + + TERRAIN_HEIGHT_RANGE_NE + + tooltip + + type + integer + value + 7 + + TERRAIN_HEIGHT_RANGE_NW + + tooltip + + type + integer + value + 6 + + TERRAIN_HEIGHT_RANGE_SE + + tooltip + + type + integer + value + 5 + + TERRAIN_HEIGHT_RANGE_SW + + tooltip + + type + integer + value + 4 + + TERRAIN_PBR_OFFSET_1 + + tooltip + + type + integer + value + 16 + + TERRAIN_PBR_OFFSET_2 + + tooltip + + type + integer + value + 17 + + TERRAIN_PBR_OFFSET_3 + + tooltip + + type + integer + value + 18 + + TERRAIN_PBR_OFFSET_4 + + tooltip + + type + integer + value + 19 + + TERRAIN_PBR_ROTATION_1 + + tooltip + + type + integer + value + 12 + + TERRAIN_PBR_ROTATION_2 + + tooltip + + type + integer + value + 13 + + TERRAIN_PBR_ROTATION_3 + + tooltip + + type + integer + value + 14 + + TERRAIN_PBR_ROTATION_4 + + tooltip + + type + integer + value + 15 + + TERRAIN_PBR_SCALE_1 + + tooltip + + type + integer + value + 8 + + TERRAIN_PBR_SCALE_2 + + tooltip + + type + integer + value + 9 + + TERRAIN_PBR_SCALE_3 + + tooltip + + type + integer + value + 10 + + TERRAIN_PBR_SCALE_4 + + tooltip + + type + integer + value + 11 + + TEXTURE_BLANK + + tooltip + + type + string + value + 5748decc-f629-461c-9a36-a35a221fe21f + + TEXTURE_DEFAULT + + tooltip + + type + string + value + 89556747-24cb-43ed-920b-47caed15465f + + TEXTURE_MEDIA + + tooltip + + type + string + value + 8b5fec65-8d8d-9dc5-cda8-8fdf2716e361 + + TEXTURE_PLYWOOD + + tooltip + + type + string + value + 89556747-24cb-43ed-920b-47caed15465f + + TEXTURE_TRANSPARENT + + tooltip + + type + string + value + 8dcd4a48-2d37-4909-9f78-f7a9eb4ef903 + + TOUCH_INVALID_FACE + + tooltip + + type + integer + value + -1 + + TOUCH_INVALID_TEXCOORD + + tooltip + + type + vector + value + <-1.0, -1.0, 0.0> + + TOUCH_INVALID_VECTOR + + tooltip + + type + vector + value + <0.0, 0.0, 0.0> + + TP_ROUTING_BLOCKED + + tooltip + Direct teleporting is blocked on this parcel. + type + integer + value + 0 + + TP_ROUTING_FREE + + tooltip + Teleports are unrestricted on this parcel. + type + integer + value + 2 + + TP_ROUTING_LANDINGP + + tooltip + Teleports are routed to a landing point if set on this parcel. + type + integer + value + 1 + + TRANSFER_BAD_OPTS + + tooltip + Invalid inventory options. + type + integer + value + -1 + + TRANSFER_BAD_ROOT + + tooltip + The root path specified in TRANSFER_DEST contained an invalid directory or was reduced to nothing. + type + integer + value + -5 + + TRANSFER_DEST + + tooltip + The root folder to transfer inventory into. + type + integer + value + 0 + + TRANSFER_FLAGS + + tooltip + Flags to control the behavior of inventory transfer. + type + integer + value + 1 + + TRANSFER_FLAG_COPY + + tooltip + Gives a copy of the object being transfered. Implies TRANSFER_FLAG_TAKE. + type + integer + value + 0x0004 + + TRANSFER_FLAG_RESERVED + + tooltip + Reserved for future expansion. + type + integer + value + 0x0001 + + TRANSFER_FLAG_TAKE + + tooltip + On a successful transfer, automatically takes the object into inventory. + type + integer + value + 0x0002 + + TRANSFER_NO_ATTACHMENT + + tooltip + Can not transfer ownership of an attached object. + type + integer + value + -7 + + TRANSFER_NO_ITEMS + + tooltip + No items in the inventory list are eligible for transfer. + type + integer + value + -4 + + TRANSFER_NO_PERMS + + tooltip + The object does not have transfer permissions. + type + integer + value + -6 + + TRANSFER_NO_TARGET + + tooltip + Could not find the receiver in the current region. + type + integer + value + -2 + + TRANSFER_OK + + tooltip + Inventory transfer offer was successfully made. + type + integer + value + 0 + + TRANSFER_THROTTLE + + tooltip + Inventory throttle hit. + type + integer + value + -3 + + TRAVERSAL_TYPE + + tooltip + One of TRAVERSAL_TYPE_FAST, TRAVERSAL_TYPE_SLOW, and TRAVERSAL_TYPE_NONE. + type + integer + value + 7 + + TRAVERSAL_TYPE_FAST + + tooltip + + type + integer + value + 1 + + TRAVERSAL_TYPE_NONE + + tooltip + + type + integer + value + 2 + + TRAVERSAL_TYPE_SLOW + + tooltip + + type + integer + value + 0 + + TRUE + + tooltip + An integer constant for boolean comparisons. Has the value '1'. + type + integer + value + 1 + + TWO_PI + + tooltip + 6.28318530 - The radians of a circle. + type + float + value + 6.28318530 + + TYPE_FLOAT + + tooltip + The list entry is a float. + type + integer + value + 2 + + TYPE_INTEGER + + tooltip + The list entry is an integer. + type + integer + value + 1 + + TYPE_INVALID + + tooltip + The list entry is invalid. + type + integer + value + 0 + + TYPE_KEY + + tooltip + The list entry is a key. + type + integer + value + 4 + + TYPE_ROTATION + + tooltip + The list entry is a rotation. + type + integer + value + 6 + + TYPE_STRING + + tooltip + The list entry is a string. + type + integer + value + 3 + + TYPE_VECTOR + + tooltip + The list entry is a vector. + type + integer + value + 5 + + URL_REQUEST_DENIED + + tooltip + + type + string + value + URL_REQUEST_DENIED + + URL_REQUEST_GRANTED + + tooltip + + type + string + value + URL_REQUEST_GRANTED + + VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY + + tooltip + A slider between minimum (0.0) and maximum (1.0) deflection of angular orientation. That is, its a simple scalar for modulating the strength of angular deflection such that the vehicles preferred axis of motion points toward its real velocity. + type + integer + value + 32 + + VEHICLE_ANGULAR_DEFLECTION_TIMESCALE + + tooltip + The time-scale for exponential success of linear deflection deflection. Its another way to specify the strength of the vehicles tendency to reorient itself so that its preferred axis of motion agrees with its true velocity. + type + integer + value + 33 + + VEHICLE_ANGULAR_FRICTION_TIMESCALE + + tooltip + + A vector of timescales for exponential decay of the vehicles angular velocity about its preferred axes of motion (at, left, up). + Range = [0.07, inf) seconds for each element of the vector. + + type + integer + value + 17 + + VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE + + tooltip + The timescale for exponential decay of the angular motors magnitude. + type + integer + value + 35 + + VEHICLE_ANGULAR_MOTOR_DIRECTION + + tooltip + The direction and magnitude (in preferred frame) of the vehicles angular motor.The vehicle will accelerate (or decelerate if necessary) to match its velocity to its motor. + type + integer + value + 19 + + VEHICLE_ANGULAR_MOTOR_TIMESCALE + + tooltip + The timescale for exponential approach to full angular motor velocity. + type + integer + value + 34 + + VEHICLE_BANKING_EFFICIENCY + + tooltip + A slider between anti (-1.0), none (0.0), and maxmum (1.0) banking strength. + type + integer + value + 38 + + VEHICLE_BANKING_MIX + + tooltip + A slider between static (0.0) and dynamic (1.0) banking. "Static" means the banking scales only with the angle of roll, whereas "dynamic" is a term that also scales with the vehicles linear speed. + type + integer + value + 39 + + VEHICLE_BANKING_TIMESCALE + + tooltip + The timescale for banking to exponentially approach its maximum effect. This is another way to scale the strength of the banking effect, however it affects the term that is proportional to the difference between what the banking behavior is trying to do, and what the vehicle is actually doing. + type + integer + value + 40 + + VEHICLE_BUOYANCY + + tooltip + A slider between minimum (0.0) and maximum anti-gravity (1.0). + type + integer + value + 27 + + VEHICLE_FLAG_BLOCK_INTERFERENCE + + tooltip + Prevent other scripts from pushing vehicle. + type + integer + value + 0x400 + + VEHICLE_FLAG_CAMERA_DECOUPLED + + tooltip + + type + integer + value + 0x200 + + VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT + + tooltip + Hover at global height. + type + integer + value + 0x10 + + VEHICLE_FLAG_HOVER_TERRAIN_ONLY + + tooltip + Ignore water height when hovering. + type + integer + value + 0x8 + + VEHICLE_FLAG_HOVER_UP_ONLY + + tooltip + Hover does not push down. Use this flag for hovering vehicles that should be able to jump above their hover height. + type + integer + value + 0x20 + + VEHICLE_FLAG_HOVER_WATER_ONLY + + tooltip + Ignore terrain height when hovering. + type + integer + value + 0x4 + + VEHICLE_FLAG_LIMIT_MOTOR_UP + + tooltip + Prevents ground vehicles from motoring into the sky. + type + integer + value + 0x40 + + VEHICLE_FLAG_LIMIT_ROLL_ONLY + + tooltip + For vehicles with vertical attractor that want to be able to climb/dive, for instance, aeroplanes that want to use the banking feature. + type + integer + value + 0x2 + + VEHICLE_FLAG_MOUSELOOK_BANK + + tooltip + + type + integer + value + 0x100 + + VEHICLE_FLAG_MOUSELOOK_STEER + + tooltip + + type + integer + value + 0x80 + + VEHICLE_FLAG_NO_DEFLECTION_UP + + tooltip + This flag prevents linear deflection parallel to world z-axis. This is useful for preventing ground vehicles with large linear deflection, like bumper cars, from climbing their linear deflection into the sky. + type + integer + value + 0x1 + + VEHICLE_FLAG_NO_FLY_UP + + deprecated + 1 + tooltip + Old, changed to VEHICLE_FLAG_NO_DEFLECTION_UP + type + integer + value + 0x1 + + VEHICLE_HOVER_EFFICIENCY + + tooltip + A slider between minimum (0.0 = bouncy) and maximum (1.0 = fast as possible) damped motion of the hover behavior. + type + integer + value + 25 + + VEHICLE_HOVER_HEIGHT + + tooltip + The height (above the terrain or water, or global) at which the vehicle will try to hover. + type + integer + value + 24 + + VEHICLE_HOVER_TIMESCALE + + tooltip + Period of time (in seconds) for the vehicle to achieve its hover height. + type + integer + value + 26 + + VEHICLE_LINEAR_DEFLECTION_EFFICIENCY + + tooltip + A slider between minimum (0.0) and maximum (1.0) deflection of linear velocity. That is, its a simple scalar for modulating the strength of linear deflection. + type + integer + value + 28 + + VEHICLE_LINEAR_DEFLECTION_TIMESCALE + + tooltip + The timescale for exponential success of linear deflection deflection. It is another way to specify how much time it takes for the vehicles linear velocity to be redirected to its preferred axis of motion. + type + integer + value + 29 + + VEHICLE_LINEAR_FRICTION_TIMESCALE + + tooltip + + A vector of timescales for exponential decay of the vehicles linear velocity along its preferred axes of motion (at, left, up). + Range = [0.07, inf) seconds for each element of the vector. + + type + integer + value + 16 + + VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE + + tooltip + The timescale for exponential decay of the linear motors magnitude. + type + integer + value + 31 + + VEHICLE_LINEAR_MOTOR_DIRECTION + + tooltip + + The direction and magnitude (in preferred frame) of the vehicles linear motor. The vehicle will accelerate (or decelerate if necessary) to match its velocity to its motor. + Range of magnitude = [0, 30] meters/second. + + type + integer + value + 18 + + VEHICLE_LINEAR_MOTOR_OFFSET + + tooltip + + type + integer + value + 20 + + VEHICLE_LINEAR_MOTOR_TIMESCALE + + tooltip + The timescale for exponential approach to full linear motor velocity. + type + integer + value + 30 + + VEHICLE_REFERENCE_FRAME + + tooltip + A rotation of the vehicles preferred axes of motion and orientation (at, left, up) with respect to the vehicles local frame (x, y, z). + type + integer + value + 44 + + VEHICLE_TYPE_AIRPLANE + + tooltip + Uses linear deflection for lift, no hover, and banking to turn.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_AIRPLANE + type + integer + value + 4 + + VEHICLE_TYPE_BALLOON + + tooltip + Hover, and friction, but no deflection.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_BALLOON + type + integer + value + 5 + + VEHICLE_TYPE_BOAT + + tooltip + Hovers over water with lots of friction and some anglar deflection.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_BOAT + type + integer + value + 3 + + VEHICLE_TYPE_CAR + + tooltip + Another vehicle that bounces along the ground but needs the motors to be driven from external controls or timer events.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_CAR + type + integer + value + 2 + + VEHICLE_TYPE_NONE + + tooltip + + type + integer + value + 0 + + VEHICLE_TYPE_SLED + + tooltip + Simple vehicle that bumps along the ground, and likes to move along its local x-axis.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_SLED + type + integer + value + 1 + + VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY + + tooltip + A slider between minimum (0.0 = wobbly) and maximum (1.0 = firm as possible) stability of the vehicle to keep itself upright. + type + integer + value + 36 + + VEHICLE_VERTICAL_ATTRACTION_TIMESCALE + + tooltip + The period of wobble, or timescale for exponential approach, of the vehicle to rotate such that its preferred "up" axis is oriented along the worlds "up" axis. + type + integer + value + 37 + + VERTICAL + + tooltip + + type + integer + value + 0 + + WANDER_PAUSE_AT_WAYPOINTS + + tooltip + + type + integer + value + 0 + + WATER_BLUR_MULTIPLIER + + tooltip + Blur factor. + type + integer + value + 100 + + WATER_FOG + + tooltip + Fog properties when underwater. + type + integer + value + 101 + + WATER_FRESNEL + + tooltip + Fresnel scattering applied to the surface of the water. + type + integer + value + 102 + + WATER_NORMAL_SCALE + + tooltip + Scaling applied to the water normal map. + type + integer + value + 104 + + WATER_NORMAL_TEXTURE + + tooltip + Normal map used for environmental waves. + type + integer + value + 107 + + WATER_REFRACTION + + tooltip + Refraction factors when looking through the surface of the water. + type + integer + value + 105 + + WATER_TEXTURE_DEFAULTS + + tooltip + Is the environment using the default wave map. + type + integer + value + 103 + + WATER_WAVE_DIRECTION + + tooltip + Vectors for the directions of the waves. + type + integer + value + 106 + + XP_ERROR_EXPERIENCES_DISABLED + + tooltip + The region currently has experiences disabled. + type + integer + value + 2 + + XP_ERROR_EXPERIENCE_DISABLED + + tooltip + The experience owner has temporarily disabled the experience. + type + integer + value + 8 + + XP_ERROR_EXPERIENCE_SUSPENDED + + tooltip + The experience has been suspended by Linden Customer Support. + type + integer + value + 9 + + XP_ERROR_INVALID_EXPERIENCE + + tooltip + The script is associated with an experience that no longer exists. + type + integer + value + 7 + + XP_ERROR_INVALID_PARAMETERS + + tooltip + One of the string arguments was too big to fit in the key-value store. + type + integer + value + 3 + + XP_ERROR_KEY_NOT_FOUND + + tooltip + The requested key does not exist. + type + integer + value + 14 + + XP_ERROR_MATURITY_EXCEEDED + + tooltip + The content rating of the experience exceeds that of the region. + type + integer + value + 16 + + XP_ERROR_NONE + + tooltip + No error was detected. + type + integer + value + 0 + + XP_ERROR_NOT_FOUND + + tooltip + The sim was unable to verify the validity of the experience. Retrying after a short wait is advised. + type + integer + value + 6 + + XP_ERROR_NOT_PERMITTED + + tooltip + This experience is not allowed to run by the requested agent. + type + integer + value + 4 + + XP_ERROR_NOT_PERMITTED_LAND + + tooltip + This experience is not allowed to run on the current region. + type + integer + value + 17 + + XP_ERROR_NO_EXPERIENCE + + tooltip + This script is not associated with an experience. + type + integer + value + 5 + + XP_ERROR_QUOTA_EXCEEDED + + tooltip + An attempted write data to the key-value store failed due to the data quota being met. + type + integer + value + 11 + + XP_ERROR_REQUEST_PERM_TIMEOUT + + tooltip + Request timed out; permissions not modified. + type + integer + value + 18 + + XP_ERROR_RETRY_UPDATE + + tooltip + A checked update failed due to an out of date request. + type + integer + value + 15 + + XP_ERROR_STORAGE_EXCEPTION + + tooltip + Unable to communicate with the key-value store. + type + integer + value + 13 + + XP_ERROR_STORE_DISABLED + + tooltip + The key-value store is currently disabled on this region. + type + integer + value + 12 + + XP_ERROR_THROTTLED + + tooltip + The call failed due to too many recent calls. + type + integer + value + 1 + + XP_ERROR_UNKNOWN_ERROR + + tooltip + Other unknown error. + type + integer + value + 10 + + ZERO_ROTATION + + tooltip + + type + rotation + value + <0.0, 0.0, 0.0, 1.0> + + ZERO_VECTOR + + tooltip + + type + vector + value + <0.0, 0.0, 0.0> + + default + + tooltip + + All scripts must have a default state, which is the first state entered when the script starts. + If another state is defined before the default state, the compiler will report a syntax error. + + + + events + + at_rot_target + + arguments + + + TargetNumber + + tooltip + + type + integer + + + + TargetRotation + + tooltip + + type + rotation + + + + CurrentRotation + + tooltip + + type + rotation + + + + tooltip + This event is triggered when a script comes within a defined angle of a target rotation. The range and rotation, are set by a call to llRotTarget. + + at_target + + arguments + + + TargetNumber + + tooltip + + type + integer + + + + TargetPosition + + tooltip + + type + vector + + + + CurrentPosition + + tooltip + + type + vector + + + + tooltip + This event is triggered when the scripted object comes within a defined range of the target position, defined by the llTarget function call. + + attach + + arguments + + + AvatarID + + tooltip + + type + key + + + + tooltip + This event is triggered whenever an object is attached or detached from an avatar. If it is attached, the key of the avatar it is attached to is passed in, otherwise NULL_KEY is. + + changed + + arguments + + + Changed + + tooltip + + type + integer + + + + tooltip + Triggered when various events change the object. The change argument will be a bit-field of CHANGED_* constants. + + collision + + arguments + + + NumberOfCollisions + + tooltip + + type + integer + + + + tooltip + + This event is raised while another object, or avatar, is colliding with the object the script is attached to. + The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* functions. + + + collision_end + + arguments + + + NumberOfCollisions + + tooltip + + type + integer + + + + tooltip + + This event is raised when another object, or avatar, stops colliding with the object the script is attached to. + The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* library functions. + + + collision_start + + arguments + + + NumberOfCollisions + + tooltip + + type + integer + + + + tooltip + + This event is raised when another object, or avatar, starts colliding with the object the script is attached to. + The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* library functions. + + + control + + arguments + + + AvatarID + + tooltip + + type + key + + + + Levels + + tooltip + + type + integer + + + + Edges + + tooltip + + type + integer + + + + tooltip + + Once a script has the ability to grab control inputs from the avatar, this event will be used to pass the commands into the script. + The levels and edges are bit-fields of control constants. + + + dataserver + + arguments + + + RequestID + + tooltip + + type + key + + + + Data + + tooltip + + type + string + + + + tooltip + + This event is triggered when the requested data is returned to the script. + Data may be requested by the llRequestAgentData, llRequestInventoryData, and llGetNotecardLine function calls, for example. + + + email + + arguments + + + Time + + tooltip + + type + string + + + + Address + + tooltip + + type + string + + + + Subject + + tooltip + + type + string + + + + Body + + tooltip + + type + string + + + + NumberRemaining + + tooltip + + type + integer + + + + tooltip + + This event is triggered when an email sent to this script arrives. + The number remaining tells how many more emails are known to be still pending. + + + experience_permissions + + arguments + + + agent_id + + tooltip + ID of the agent approving permission for the Experience. + type + key + + + + tooltip + Triggered when an agent has approved an experience permissions request. + + experience_permissions_denied + + arguments + + + agent_id + + tooltip + ID of the agent denying permission for the Experience. + type + key + + + + Reason + + tooltip + One of the XP_ERROR_... constants describing the reason why the Experience permissions were denied for the agent. + type + integer + + + + tooltip + Describes why the Experience permissions were denied for the agent. + + final_damage + + arguments + + + count + + tooltip + The number of damage events queued. + type + integer + + + + tooltip + Triggered as damage is applied to an avatar or task, after all on_damage events have been processed. + + game_control + + arguments + + + id + + tooltip + UUID of avatar supplying input + type + key + + + + buttons + + tooltip + 32-bit mask of buttons pressed + type + integer + + + + axes + + tooltip + Six float values in range [-1, 1] + type + list + + + + tooltip + This event is raised when game controller input changes. + + http_request + + arguments + + + HTTPRequestID + + tooltip + + type + key + + + + HTTPMethod + + tooltip + + type + string + + + + Body + + tooltip + + type + string + + + + tooltip + Triggered when task receives an HTTP request. + + http_response + + arguments + + + HTTPRequestID + + tooltip + + type + key + + + + Status + + tooltip + + type + integer + + + + Metadata + + tooltip + + type + list + + + + Body + + tooltip + + type + string + + + + tooltip + This event handler is invoked when an HTTP response is received for a pending llHTTPRequest request or if a pending request fails or times out. + + land_collision + + arguments + + + Position + + tooltip + + type + vector + + + + tooltip + This event is raised when the object the script is attached to is colliding with the ground. + + land_collision_end + + arguments + + + Position + + tooltip + + type + vector + + + + tooltip + This event is raised when the object the script is attached to stops colliding with the ground. + + land_collision_start + + arguments + + + Position + + tooltip + + type + vector + + + + tooltip + This event is raised when the object the script is attached to begins to collide with the ground. + + link_message + + arguments + + + SendersLink + + tooltip + + type + integer + + + + Value + + tooltip + + type + integer + + + + Text + + tooltip + + type + string + + + + ID + + tooltip + + type + key + + + + tooltip + Triggered when object receives a link message via llMessageLinked function call. + + linkset_data + + arguments + + + action + + tooltip + + type + integer + + + + name + + tooltip + + type + string + + + + value + + tooltip + + type + string + + + + tooltip + Triggered when a script modifies the linkset datastore. + + listen + + arguments + + + Channel + + tooltip + + type + integer + + + + Name + + tooltip + + type + string + + + + ID + + tooltip + + type + key + + + + Text + + tooltip + + type + string + + + + tooltip + + This event is raised whenever a chat message matching the constraints set in the llListen command is received. The name and ID of the speaker, as well as the message, are passed in as parameters. + Channel 0 is the public chat channel that all avatars see as chat text. Channels 1 through 2,147,483,648 are private channels that are not sent to avatars but other scripts can listen on those channels. + + + money + + arguments + + + Payer + + tooltip + + type + key + + + + Amount + + tooltip + + type + integer + + + + tooltip + This event is triggered when a resident has given an amount of Linden dollars to the object. + + moving_end + + arguments + + tooltip + Triggered whenever an object with this script stops moving. + + moving_start + + arguments + + tooltip + Triggered whenever an object with this script starts moving. + + no_sensor + + arguments + + tooltip + This event is raised when sensors are active, via the llSensor function call, but are not sensing anything. + + not_at_rot_target + + arguments + + tooltip + When a target is set via the llRotTarget function call, but the script is outside the specified angle this event is raised. + + not_at_target + + arguments + + tooltip + When a target is set via the llTarget library call, but the script is outside the specified range this event is raised. + + object_rez + + arguments + + + RezzedObjectsID + + tooltip + + type + key + + + + tooltip + Triggered when an object rezzes another object from its inventory via the llRezObject, or similar, functions. The id is the globally unique key for the object rezzed. + + on_damage + + arguments + + + count + + tooltip + The number of damage events queued. + type + integer + + + + tooltip + Triggered when an avatar or object receives damage. + + on_death + + arguments + + tooltip + Triggered when an avatar reaches 0 health. + + on_rez + + arguments + + + StartParameter + + tooltip + + type + integer + + + + tooltip + Triggered whenever an object is rezzed from inventory or by another object. The start parameter is passed in from the llRezObject call, or zero if from inventory. + + path_update + + arguments + + + Type + + tooltip + + type + integer + + + + Reserved + + tooltip + + type + list + + + + tooltip + This event is called to inform the script of changes within the object's path-finding status. + + remote_data + + arguments + + + EventType + + tooltip + + type + integer + + + + ChannelID + + tooltip + + type + key + + + + MessageID + + tooltip + + type + key + + + + Sender + + tooltip + + type + string + + + + IData + + tooltip + + type + integer + + + + SData + + tooltip + + type + string + + + + tooltip + This event is deprecated. + + run_time_permissions + + arguments + + + PermissionFlags + + tooltip + + type + integer + + + + tooltip + + Scripts need permission from either the owner or the avatar they wish to act on before they may perform certain functions, such as debiting money from their owners account, triggering an animation on an avatar, or capturing control inputs. The llRequestPermissions library function is used to request these permissions and the various permissions integer constants can be supplied. + The integer returned to this event handler contains the current set of permissions flags, so if permissions equal 0 then no permissions are set. + + + sensor + + arguments + + + NumberDetected + + tooltip + + type + integer + + + + tooltip + + This event is raised whenever objects matching the constraints of the llSensor command are detected. + The number of detected objects is passed to the script in the parameter. Information on those objects may be gathered via the llDetected* functions. + + + state_entry + + arguments + + tooltip + The state_entry event occurs whenever a new state is entered, including at program start, and is always the first event handled. + + state_exit + + arguments + + tooltip + The state_exit event occurs whenever the state command is used to transition to another state. It is handled before the new states state_entry event. + + timer + + arguments + + tooltip + This event is raised at regular intervals set by the llSetTimerEvent library function. + + touch + + arguments + + + NumberOfTouches + + tooltip + + type + integer + + + + tooltip + + This event is raised while a user is touching the object the script is attached to. + The number of touching objects is passed to the script in the parameter. + Information on those objects may be gathered via the llDetected* library functions. + + + touch_end + + arguments + + + NumberOfTouches + + tooltip + + type + integer + + + + tooltip + + This event is raised when a user stops touching the object the script is attached to. The number of touches is passed to the script in the parameter. + Information on those objects may be gathered via the llDetected* library functions. + + + touch_start + + arguments + + + NumberOfTouches + + tooltip + + type + integer + + + + tooltip + + This event is raised when a user first touches the object the script is attached to. The number of touches is passed to the script in the parameter. + Information on those objects may be gathered via the llDetected() library functions. + + + transaction_result + + arguments + + + RequestID + + tooltip + + type + key + + + + Success + + tooltip + + type + integer + + + + Message + + tooltip + + type + string + + + + tooltip + Triggered by llTransferMoney() function. + + + functions + + llAbs + + arguments + + + Value + + tooltip + An integer value. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the absolute (positive) version of Value. + + llAcos + + arguments + + + Value + + tooltip + A floating-point value. + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the arc-cosine of Value, in radians. + + llAddToLandBanList + + arguments + + + ID + + tooltip + Agent UUID to add to ban-list. + type + key + + + + Hours + + tooltip + Period, in hours, to ban the avatar for. + type + float + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Add avatar ID to the parcel ban list for the specified number of Hours.\nA value of 0 for Hours will add the agent indefinitely.\nThe smallest value that Hours will accept is 0.01; anything smaller will be seen as 0.\nWhen values that small are used, it seems the function bans in approximately 30 second increments (Probably 36 second increments, as 0.01 of an hour is 36 seconds).\nResidents teleporting to a parcel where they are banned will be redirected to a neighbouring parcel. + + llAddToLandPassList + + arguments + + + ID + + tooltip + Agent UUID to add to pass-list. + type + key + + + + Hours + + tooltip + Period, in hours, to allow the avatar for. + type + float + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Add avatar ID to the land pass list, for a duration of Hours. + + llAdjustDamage + + arguments + + + Number + + tooltip + Damage event index to modify. + type + integer + + + + Damage + + tooltip + New damage amount to apply on this event. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Changes the amount of damage to be delivered by this damage event. + + llAdjustSoundVolume + + arguments + + + Volume + + tooltip + The volume to set. + type + float + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Adjusts the volume (0.0 - 1.0) of the currently playing attached sound.\nThis function has no effect on sounds started with llTriggerSound. + + llAgentInExperience + + arguments + + + AgentID + + tooltip + + type + key + + + + energy + 10 + return + integer + sleep + 0 + tooltip + + Returns TRUE if the agent is in the Experience and the Experience can run in the current location. + + + llAllowInventoryDrop + + arguments + + + Flag + + tooltip + Boolean, If TRUE allows anyone to drop inventory on prim, FALSE revokes. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + If Flag == TRUE, users without object modify permissions can still drop inventory items into the object. + + llAngleBetween + + arguments + - TargetNumber + Rot1 + + tooltip + First rotation. + type + rotation + + + + Rot2 + + tooltip + Second rotation. + type + rotation + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the angle, in radians, between rotations Rot1 and Rot2. + + llApplyImpulse + + arguments + + + Force + + tooltip + Amount of impulse force to apply. + type + vector + + + + Local + tooltip + Boolean, if TRUE, force is treated as a local directional vector instead of region directional vector. type integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Applies impulse to the object.\nIf Local == TRUE, apply the Force in local coordinates; otherwise, apply the Force in global coordinates.\nThis function only works on physical objects. + + llApplyRotationalImpulse + + arguments + + + Force + tooltip - + Amount of impulse force to apply. + type + vector - TargetRotation + Local + tooltip + Boolean, if TRUE, uses local axis, if FALSE, uses region axis. type - rotation + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Applies rotational impulse to the object.\nIf Local == TRUE, apply the Force in local coordinates; otherwise, apply the Force in global coordinates.\nThis function only works on physical objects. + + llAsin + + arguments + + + Value + tooltip - + A floating-point value. + type + float + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the arc-sine, in radians, of Value. + + llAtan2 + + arguments + - CurrentRotation + y + tooltip + A floating-point value. type - rotation + float + + + + x + tooltip - + A floating-point value. + type + float + energy + 10 + return + float + sleep + 0 tooltip - This event is triggered when a script comes within a defined angle of a target rotation. The range and rotation, are set by a call to llRotTarget. + Returns the arc-tangent2 of y, x. - at_target + llAttachToAvatar arguments - TargetNumber + AttachmentPoint + tooltip + type integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Attach to avatar at point AttachmentPoint.\nRequires the PERMISSION_ATTACH runtime permission. + + llAttachToAvatarTemp + + arguments + + + AttachPoint + tooltip - + Valid attachment point or ATTACH_* constant. + type + integer + + energy + 10 + return + void + sleep + 0 + tooltip + Follows the same convention as llAttachToAvatar, with the exception that the object will not create new inventory for the user, and will disappear on detach or disconnect. + + llAvatarOnLinkSitTarget + + arguments + - TargetPosition + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + If an avatar is sitting on the link's sit target, return the avatar's key, NULL_KEY otherwise.\nReturns a key that is the UUID of the user seated on the specified link's prim. + + llAvatarOnSitTarget + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + If an avatar is seated on the sit target, returns the avatar's key, otherwise NULL_KEY.\nThis only will detect avatars sitting on sit targets defined with llSitTarget. + + llAxes2Rot + + arguments + + + Forward + tooltip + Forward/Back part of rotation. type vector + + + + Left + tooltip - + Left/Right part of rotation. + type + vector - CurrentPosition + Up + tooltip + Up/Down part of rotation. + type + vector + + + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation represented by coordinate axes Forward, Left, and Up. + + llAxisAngle2Rot + + arguments + + + Axis + + tooltip + Axis. type vector + + + + Angle + tooltip - + Angle in radians. + type + float + energy + 10 + return + rotation + sleep + 0 tooltip - This event is triggered when the scripted object comes within a defined range of the target position, defined by the llTarget function call. + Returns the rotation that is a generated Angle about Axis. - attach + llBase64ToInteger arguments - AvatarID + Text - type - key tooltip - + + type + string + energy + 10 + return + integer + sleep + 0 tooltip - This event is triggered whenever an object is attached or detached from an avatar. If it is attached, the key of the avatar it is attached to is passed in, otherwise NULL_KEY is. + Returns an integer that is the Text, Base64 decoded as a big endian integer.\nReturns zero if Text is longer then 8 characters. If Text contains fewer then 6 characters, the return value is unpredictable. - changed + llBase64ToString arguments - Changed + Text - type - integer tooltip - + + type + string + energy + 10 + return + string + sleep + 0 tooltip - Triggered when various events change the object. The change argument will be a bit-field of CHANGED_* constants. + Converts a Base64 string to a conventional string.\nIf the conversion creates any unprintable characters, they are converted to question marks. - collision + llBreakAllLinks arguments - - - NumberOfCollisions - - type - integer - tooltip - - - - + + energy + 10 + return + void + sleep + 0 tooltip - This event is raised while another object, or avatar, is colliding with the object the script is attached to. - The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* functions. + De-links all prims in the link set (requires permission PERMISSION_CHANGE_LINKS be set). - collision_end + llBreakLink arguments - NumberOfCollisions + LinkNumber + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - This event is raised when another object, or avatar, stops colliding with the object the script is attached to. - The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* library functions. + De-links the prim with the given link number (requires permission PERMISSION_CHANGE_LINKS be set). - collision_start + llCSV2List arguments - NumberOfCollisions + Text - type - integer tooltip - + + type + string + energy + 10 + return + list + sleep + 0 tooltip - This event is raised when another object, or avatar, starts colliding with the object the script is attached to. - The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* library functions. + Create a list from a string of comma separated values specified in Text. - control + llCastRay arguments - AvatarID + Start - type - key tooltip - + + type + vector - Levels + End - type - integer tooltip - + + type + vector - Edges + Options - type - integer tooltip - + + type + list + energy + 10 + return + list + sleep + 0 tooltip - Once a script has the ability to grab control inputs from the avatar, this event will be used to pass the commands into the script. - The levels and edges are bit-fields of control constants. + Casts a ray into the physics world from 'start' to 'end' and returns data according to details in Options.\nReports collision data for intersections with objects.\nReturn value: [UUID_1, {link_number_1}, hit_position_1, {hit_normal_1}, UUID_2, {link_number_2}, hit_position_2, {hit_normal_2}, ... , status_code] where {} indicates optional data. - dataserver + llCeil arguments - RequestID + Value - type - key tooltip - - - - - Data - + type - string - tooltip - + float + energy + 10 + return + integer + sleep + 0 tooltip - This event is triggered when the requested data is returned to the script. - Data may be requested by the llRequestAgentData, llRequestInventoryData, and llGetNotecardLine function calls, for example. + Returns smallest integer value >= Value. - email + llChar arguments - Time + value - type - string tooltip - - - - - Address - + Unicode value to convert into a string. type - string - tooltip - + integer + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a single character string that is the representation of the unicode value. + + llClearCameraParams + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Resets all camera parameters to default values and turns off scripted camera control. + + llClearLinkMedia + + arguments + - Subject + Link - type - string tooltip - - - - - Body - + type - string - tooltip - + integer - NumberRemaining + Face + tooltip + type integer - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip - This event is triggered when an email sent to this script arrives. - The number remaining tells how many more emails are known to be still pending. - - experience_permissions - - arguments - - - agent_id - - type - key - tooltip - ID of the agent approving permission for the Experience. - - - + Clears (deletes) the media and all parameters from the given Face on the linked prim.\nReturns an integer that is a STATUS_* flag, which details the success/failure of the operation. - experience_permissions_denied + llClearPrimMedia arguments - - agent_id - - type - key - tooltip - ID of the agent denying permission for the Experience. - - - - Reason - - type - integer - tooltip - One of the XP_ERROR_... constants describing the reason why the Experience permissions were denied for the agent. - - + + Face + + tooltip + Number of side to clear. + type + integer + + + energy + 10 + return + integer + sleep + 1 tooltip - Describes why the Experience permissions were denied for the agent. + Clears (deletes) the media and all parameters from the given Face.\nReturns an integer that is a STATUS_* flag which details the success/failure of the operation. - http_request + llCloseRemoteDataChannel arguments - HTTPRequestID + ChannelID + tooltip + type key - tooltip - + + energy + 10 + return + void + sleep + 1 + tooltip + This function is deprecated. + + llCloud + + arguments + - HTTPMethod + Offset - type - string tooltip - - - - - Body - + type - string - tooltip - + vector + energy + 10 + return + float + sleep + 0 tooltip - Triggered when task receives an HTTP request. + Returns the cloud density at the object's position + Offset. - http_response + llCollisionFilter arguments - HTTPRequestID - - type - key - tooltip - - - - - Status + ObjectName - type - integer tooltip - + + type + string - Metadata + ObjectID - type - list tooltip - + + type + key - Body + Accept - type - string tooltip - + If TRUE, only accept collisions with ObjectName name AND ObjectID (either is optional), otherwise with objects not ObjectName AND ObjectID. + type + integer + energy + 10 + return + void + sleep + 0 tooltip - This event handler is invoked when an HTTP response is received for a pending llHTTPRequest request or if a pending request fails or times out. + Specify an empty string or NULL_KEY for Accept, to not filter on the corresponding parameter. - land_collision + llCollisionSound arguments - Position + ImpactSound - type - vector tooltip - + + type + string - - tooltip - This event is raised when the object the script is attached to is colliding with the ground. - - land_collision_end - - arguments - - Position + ImpactVolume - type - vector tooltip - + + type + float + energy + 10 + return + void + sleep + 0 tooltip - This event is raised when the object the script is attached to stops colliding with the ground. + Suppress default collision sounds, replace default impact sounds with ImpactSound.\nThe ImpactSound must be in the object inventory.\nSupply an empty string to suppress collision sounds. - land_collision_start + llCollisionSprite arguments - Position + ImpactSprite - type - vector tooltip - + + type + string + energy + 10 + return + void + sleep + 0 tooltip - This event is raised when the object the script is attached to begins to collide with the ground. + Suppress default collision sprites, replace default impact sprite with ImpactSprite; found in the object inventory (empty string to just suppress). - link_message + llComputeHash arguments - SendersLink + Message - type - integer tooltip - - - - - Value - + The message to be hashed. type - integer - tooltip - + string - Text + Algorithm + tooltip + The digest algorithm: md5, sha1, sha224, sha256, sha384, sha512. type string - tooltip - + + energy + 10 + return + string + sleep + 0 + tooltip + Returns hex-encoded Hash string of Message using digest Algorithm. + + llCos + + arguments + - ID + Theta - type - key tooltip - + + type + float + energy + 10 + return + float + sleep + 0 tooltip - Triggered when object receives a link message via llMessageLinked function call. + Returns the cosine of Theta (Theta in radians). - listen + llCreateCharacter arguments - Channel + Options - type - integer tooltip - + + type + list + + energy + 10 + return + void + sleep + 0 + tooltip + Convert link-set to AI/Physics character.\nCreates a path-finding entity, known as a "character", from the object containing the script. Required to activate use of path-finding functions.\nOptions is a list of key/value pairs. + + llCreateKeyValue + + arguments + - Name + Key + tooltip + type string - tooltip - - ID + Value - type - key tooltip - - - - - Text - + type string - tooltip - + energy + 10 + return + key + sleep + 0 tooltip - This event is raised whenever a chat message matching the constraints set in the llListen command is received. The name and ID of the speaker, as well as the message, are passed in as parameters. - Channel 0 is the public chat channel that all avatars see as chat text. Channels 1 through 2,147,483,648 are private channels that are not sent to avatars but other scripts can listen on those channels. + + Starts an asychronous transaction to create a key-value pair. Will fail with XP_ERROR_STORAGE_EXCEPTION if the key already exists. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value passed to the function. + - money + llCreateLink arguments - Payer + TargetPrim + tooltip + Object UUID that is in the same region. type key - tooltip - - Amount + Parent + tooltip + If FALSE, then TargetPrim becomes the root. If TRUE, then the script's object becomes the root. type integer - tooltip - + energy + 10 + return + void + sleep + 0.1000000000000000055511151 tooltip - This event is triggered when a resident has given an amount of Linden dollars to the object. - - moving_end - - arguments - - tooltip - Triggered whenever an object with this script stops moving. - - moving_start - - arguments - - tooltip - Triggered whenever an object with this script starts moving. - - no_sensor - - arguments - - tooltip - This event is raised when sensors are active, via the llSensor function call, but are not sensing anything. - - not_at_rot_target - - arguments - - tooltip - When a target is set via the llRotTarget function call, but the script is outside the specified angle this event is raised. - - not_at_target - - arguments - - tooltip - When a target is set via the llTarget library call, but the script is outside the specified range this event is raised. + Attempt to link the object the script is in, to target (requires permission PERMISSION_CHANGE_LINKS be set).\nRequires permission PERMISSION_CHANGE_LINKS be set. - object_rez + llDamage arguments - RezzedObjectsID + target + tooltip + Agent or task to receive damage. type key + + + + damage + tooltip - + Damage amount to inflict on this target. + type + float - - tooltip - Triggered when an object rezzes another object from its inventory via the llRezObject, or similar, functions. The id is the globally unique key for the object rezzed. - - on_rez - - arguments - - StartParameter + type + tooltip + Damage type to inflict on this target. type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Triggered whenever an object is rezzed from inventory or by another object. The start parameter is passed in from the llRezObject call, or zero if from inventory. + Generates a damage event on the targeted agent or task. - path_update + llDataSizeKeyValue arguments - - - Type - - type - integer - tooltip - - - + + energy + 10 + return + key + sleep + 0 + tooltip + + Starts an asychronous transaction the request the used and total amount of data allocated for the Experience. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the the amount in use and the third item will be the total available. + + + llDeleteCharacter + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Convert link-set from AI/Physics character to Physics object.\nConvert the current link-set back to a standard object, removing all path-finding properties. + + llDeleteKeyValue + + arguments + - Reserved + Key - type - list tooltip - + + type + string + energy + 10 + return + key + sleep + 0 tooltip - This event is called to inform the script of changes within the object's path-finding status. + + Starts an asychronous transaction to delete a key-value pair. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. + - remote_data + llDeleteSubList arguments - EventType + Source - type - integer tooltip - + + type + list - ChannelID + Start - type - key tooltip - + + type + integer - MessageID + End - type - key tooltip - + + type + integer + + energy + 10 + return + list + sleep + 0 + tooltip + Removes the slice from start to end and returns the remainder of the list.\nRemove a slice from the list and return the remainder, start and end are inclusive.\nUsing negative numbers for start and/or end causes the index to count backwards from the length of the list, so 0, -1 would delete the entire list.\nIf Start is larger than End the list deleted is the exclusion of the entries; so 6, 4 would delete the entire list except for the 5th. list entry. + + llDeleteSubString + + arguments + - Sender + Source + tooltip + type string - tooltip - - Data + Start + tooltip + type integer - tooltip - - Data + End - type - string tooltip - + + type + integer + energy + 10 + return + string + sleep + 0 tooltip - Triggered by various XML-RPC calls with event_type specifying the type of data. + Removes the indicated sub-string and returns the result.\nStart and End are inclusive.\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would delete the entire string.\nIf Start is larger than End, the sub-string is the exclusion of the entries; so 6, 4 would delete the entire string except for the 5th. character. - run_time_permissions + llDerezObject arguments - PermissionFlags + ID - type - integer tooltip - + The ID of an object in the region. + type + key - - tooltip - Scripts need permission from either the owner or the avatar they wish to act on before they may perform certain functions, such as debiting money from their owners account, triggering an animation on an avatar, or capturing control inputs. The llRequestPermissions library function is used to request these permissions and the various permissions integer constants can be supplied. - The integer returned to this event handler contains the current set of permissions flags, so if permissions equal 0 then no permissions are set. - - sensor - - arguments - - NumberDetected + flags + tooltip + Flags for derez behavior. type integer - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip - This event is raised whenever objects matching the constraints of the llSensor command are detected. - The number of detected objects is passed to the script in the parameter. Information on those objects may be gathered via the llDetected* functions. - - state_entry - - arguments - - tooltip - The state_entry event occurs whenever a new state is entered, including at program start, and is always the first event handled. - - state_exit - - arguments - - tooltip - The state_exit event occurs whenever the state command is used to transition to another state. It is handled before the new states state_entry event. + Derezzes an object previously rezzed by a script in this region. Returns TRUE on success or FALSE if the object could not be derezzed. - timer + llDetachFromAvatar arguments - + + energy + 10 + return + void + sleep + 0 tooltip - This event is raised at regular intervals set by the llSetTimerEvent library function. + Remove the object containing the script from the avatar. - touch + llDetectedDamage arguments - NumberOfTouches + Number + tooltip + type integer - tooltip - + energy + 10 + return + list + sleep + 0 tooltip - This event is raised while a user is touching the object the script is attached to. - The number of touching objects is passed to the script in the parameter. - Information on those objects may be gathered via the llDetected* library functions. + Returns a list containing the current damage for the event, the damage type and the original damage delivered. - touch_end + llDetectedGrab arguments - NumberOfTouches + Number + tooltip + type integer - tooltip - + energy + 10 + return + vector + sleep + 0 tooltip - This event is raised when a user stops touching the object the script is attached to. The number of touches is passed to the script in the parameter. - Information on those objects may be gathered via the llDetected* library functions. + Returns the grab offset of a user touching the object.\nReturns <0.0, 0.0, 0.0> if Number is not a valid object. - touch_start + llDetectedGroup arguments - NumberOfTouches + Number + tooltip + type integer - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip - This event is raised when a user first touches the object the script is attached to. The number of touches is passed to the script in the parameter. - Information on those objects may be gathered via the llDetected() library functions. + Returns TRUE if detected object or agent Number has the same user group active as this object.\nIt will return FALSE if the object or agent is in the group, but the group is not active. - transaction_result + llDetectedKey arguments - RequestID + Number - type - key tooltip - - - - - Success - + type integer - tooltip - - - - - Message - - type - string - tooltip - + energy + 10 + return + key + sleep + 0 tooltip - Triggered by llTransferMoney() function. + Returns the key of detected object or avatar number.\nReturns NULL_KEY if Number is not a valid index. - - functions - - llAbs + llDetectedLinkNumber - energy - 10.0 - sleep - 0.0 - return - integer arguments - Value + Number + tooltip + type integer - tooltip - An integer value. + energy + 10 + return + integer + sleep + 0 tooltip - Returns the absolute (positive) version of Value. + Returns the link position of the triggered event for touches and collisions only.\n0 for a non-linked object, 1 for the root of a linked object, 2 for the first child, etc. - llAcos + llDetectedName - energy - 10.0 - sleep - 0.0 - return - float arguments - Value + Number - type - float tooltip - A floating-point value. + + type + integer + energy + 10 + return + string + sleep + 0 tooltip - Returns the arc-cosine of Value, in radians. + Returns the name of detected object or avatar number.\nReturns the name of detected object number.\nReturns empty string if Number is not a valid index. - llAddToLandBanList + llDetectedOwner - energy - 10.0 - sleep - 0.0 - return - void arguments - ID + Number - type - key tooltip - Agent UUID to add to ban-list. - - - - Hours - + type - float - tooltip - Period, in hours, to ban the avatar for. + integer + energy + 10 + return + key + sleep + 0 tooltip - Add avatar ID to the parcel ban list for the specified number of Hours.\nA value of 0 for Hours will add the agent indefinitely.\nThe smallest value that Hours will accept is 0.01; anything smaller will be seen as 0.\nWhen values that small are used, it seems the function bans in approximately 30 second increments (Probably 36 second increments, as 0.01 of an hour is 36 seconds).\nResidents teleporting to a parcel where they are banned will be redirected to a neighbouring parcel. + Returns the key of detected object's owner.\nReturns invalid key if Number is not a valid index. - llAddToLandPassList + llDetectedPos - energy - 10.0 - sleep - 0.1 - return - void arguments - ID - - type - key - tooltip - Agent UUID to add to pass-list. - - - - Hours + Number - type - float tooltip - Period, in hours, to allow the avatar for. + + type + integer + energy + 10 + return + vector + sleep + 0 tooltip - Add avatar ID to the land pass list, for a duration of Hours. + Returns the position of detected object or avatar number.\nReturns <0.0, 0.0, 0.0> if Number is not a valid index. - llAdjustSoundVolume + llDetectedRezzer - energy - 10.0 - sleep - 0.1 - return - void arguments - Volume + Number - type - float tooltip - The volume to set. + + type + integer - tooltip - Adjusts the volume (0.0 - 1.0) of the currently playing attached sound.\nThis function has no effect on sounds started with llTriggerSound. - - llAgentInExperience - energy - 10.0 - sleep - 0.0 + 10 return - integer - arguments - - - AgentID - - type - key - tooltip - - - - + key + sleep + 0 tooltip - - Returns TRUE if the agent is in the Experience and the Experience can run in the current location. - + Returns the key for the rezzer of the detected object. - llAllowInventoryDrop + llDetectedRot - energy - 10.0 - sleep - 0.0 - return - void arguments - Flag + Number + tooltip + type integer - tooltip - Boolean, If TRUE allows anyone to drop inventory on prim, FALSE revokes. + energy + 10 + return + rotation + sleep + 0 tooltip - If Flag == TRUE, users without object modify permissions can still drop inventory items into the object. + Returns the rotation of detected object or avatar number.\nReturns <0.0, 0.0, 0.0, 1.0> if Number is not a valid offset. - llAngleBetween + llDetectedTouchBinormal - energy - 10.0 - sleep - 0.0 - return - float arguments - Rot1 + Index - type - rotation tooltip - First rotation. - - - - Rot2 - + Index of detection information type - rotation - tooltip - Second rotation. + integer + energy + 10 + return + vector + sleep + 0 tooltip - Returns the angle, in radians, between rotations Rot1 and Rot2. + Returns the surface bi-normal for a triggered touch event.\nReturns a vector that is the surface bi-normal (tangent to the surface) where the touch event was triggered. - llApplyImpulse + llDetectedTouchFace - energy - 10.0 - sleep - 0.0 - return - void arguments - Force + Index - type - vector tooltip - Amount of impulse force to apply. - - - - Local - + Index of detection information type integer - tooltip - Boolean, if TRUE, force is treated as a local directional vector instead of region directional vector. + energy + 10 + return + integer + sleep + 0 tooltip - Applies impulse to the object.\nIf Local == TRUE, apply the Force in local coordinates; otherwise, apply the Force in global coordinates.\nThis function only works on physical objects. + Returns the index of the face where the avatar clicked in a triggered touch event. - llApplyRotationalImpulse + llDetectedTouchNormal - energy - 10.0 - sleep - 0.0 - return - void arguments - Force + Index - type - vector tooltip - Amount of impulse force to apply. - - - - Local - + Index of detection information type integer - tooltip - Boolean, if TRUE, uses local axis, if FALSE, uses region axis. + energy + 10 + return + vector + sleep + 0 tooltip - Applies rotational impulse to the object.\nIf Local == TRUE, apply the Force in local coordinates; otherwise, apply the Force in global coordinates.\nThis function only works on physical objects. + Returns the surface normal for a triggered touch event.\nReturns a vector that is the surface normal (perpendicular to the surface) where the touch event was triggered. - llAsin + llDetectedTouchPos - energy - 10.0 - sleep - 0.0 - return - float arguments - Value + Index - type - float tooltip - A floating-point value. + Index of detected information + type + integer + energy + 10 + return + vector + sleep + 0 tooltip - Returns the arc-sine, in radians, of Value. + Returns the position, in region coordinates, where the object was touched in a triggered touch event.\nUnless it is a HUD, in which case it returns the position relative to the attach point. - llAtan2 + llDetectedTouchST - energy - 10.0 - sleep - 0.0 - return - float arguments - y + Index - type - float tooltip - A floating-point value. - - - - x - + Index of detection information type - float - tooltip - A floating-point value. + integer + energy + 10 + return + vector + sleep + 0 tooltip - Returns the arc-tangent2 of y, x. + Returns a vector that is the surface coordinates where the prim was touched.\nThe X and Y vector positions contain the horizontal (S) and vertical (T) face coordinates respectively.\nEach component is in the interval [0.0, 1.0].\nTOUCH_INVALID_TEXCOORD is returned if the surface coordinates cannot be determined (e.g. when the viewer does not support this function). - llAttachToAvatar + llDetectedTouchUV - energy - 10.0 - sleep - 0.0 - return - void arguments - AttachmentPoint + Index + tooltip + Index of detection information type integer - tooltip - - tooltip - Attach to avatar at point AttachmentPoint.\nRequires the PERMISSION_ATTACH runtime permission. - - llAttachToAvatarTemp - energy - 0 + 10 + return + vector sleep 0 - return - void + tooltip + Returns a vector that is the texture coordinates for where the prim was touched.\nThe X and Y vector positions contain the U and V face coordinates respectively.\nTOUCH_INVALID_TEXCOORD is returned if the touch UV coordinates cannot be determined (e.g. when the viewer does not support this function). + + llDetectedType + arguments - AttachPoint + Number + tooltip + type integer - tooltip - Valid attachment point or ATTACH_* constant. + energy + 10 + return + integer + sleep + 0 tooltip - Follows the same convention as llAttachToAvatar, with the exception that the object will not create new inventory for the user, and will disappear on detach or disconnect. + Returns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object.\nReturns 0 if number is not a valid index.\nNote that number is a bit-field, so comparisons need to be a bitwise checked. e.g.:\ninteger iType = llDetectedType(0);\n{\n // ...do stuff with the agent\n} - llAvatarOnLinkSitTarget + llDetectedVel - energy - 10.0 - sleep - 0.0 - return - key arguments - LinkNumber + Number + tooltip + type integer - tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. - tooltip - If an avatar is sitting on the link's sit target, return the avatar's key, NULL_KEY otherwise.\nReturns a key that is the UUID of the user seated on the specified link's prim. - - llAvatarOnSitTarget - energy - 10.0 - sleep - 0.0 + 10 return - key - arguments - + vector + sleep + 0 tooltip - If an avatar is seated on the sit target, returns the avatar's key, otherwise NULL_KEY.\nThis only will detect avatars sitting on sit targets defined with llSitTarget. + Returns the velocity of the detected object Number.\nReturns<0.0, 0.0, 0.0> if Number is not a valid offset. - llAxes2Rot + llDialog - energy - 10.0 - sleep - 0.0 - return - rotation arguments - Forward + AvatarID - type - vector tooltip - Forward/Back part of rotation. + + type + key - Left + Text - type - vector tooltip - Left/Right part of rotation. + + type + string - Up + Buttons + tooltip + type - vector + list + + + + Channel + tooltip - Up/Down part of rotation. + + type + integer + energy + 10 + return + void + sleep + 1 tooltip - Returns the rotation represented by coordinate axes Forward, Left, and Up. + + Shows a dialog box on the avatar's screen with the message.\n + Up to 12 strings in the list form buttons.\n + If a button is clicked, the name is chatted on Channel.\nOpens a "notify box" in the given avatars screen displaying the message.\n + Up to twelve buttons can be specified in a list of strings. When the user clicks a button, the name of the button is said on the specified channel.\n + Channels work just like llSay(), so channel 0 can be heard by everyone.\n + The chat originates at the object's position, not the avatar's position, even though it is said as the avatar (uses avatar's UUID and Name etc.).\n + Examples:\n + llDialog(who, "Are you a boy or a girl?", [ "Boy", "Girl" ], -4913);\n + llDialog(who, "This shows only an OK button.", [], -192);\n + llDialog(who, "This chats so you can 'hear' it.", ["Hooray"], 0); + - llAxisAngle2Rot + llDie + arguments + energy - 10.0 - sleep - 0.0 + 0 return - rotation + void + sleep + 0 + tooltip + Delete the object which holds the script. + + llDumpList2String + arguments - Axis + Source - type - vector tooltip - Axis. + + type + list - Angle + Separator - type - float tooltip - Angle in radians. + + type + string + energy + 10 + return + string + sleep + 0 tooltip - Returns the rotation that is a generated Angle about Axis. + Returns the list as a single string, using Separator between the entries.\nWrite the list out as a single string, using Separator between values. - llBase64ToInteger + llEdgeOfWorld - energy - 10.0 - sleep - 0.0 - return - integer arguments - Text + Position - type - string tooltip - + + type + vector - - tooltip - Returns an integer that is the Text, Base64 decoded as a big endian integer.\nReturns zero if Text is longer then 8 characters. If Text contains fewer then 6 characters, the return value is unpredictable. - - llBase64ToString - - energy - 10.0 - sleep - 0.0 - return - string - arguments - - Text + Direction - type - string tooltip - + + type + vector - tooltip - Converts a Base64 string to a conventional string.\nIf the conversion creates any unprintable characters, they are converted to question marks. - - llBreakAllLinks - energy - 10.0 - sleep - 0.0 + 10 return - void - arguments - + integer + sleep + 0 tooltip - De-links all prims in the link set (requires permission PERMISSION_CHANGE_LINKS be set). + Checks to see whether the border hit by Direction from Position is the edge of the world (has no neighboring region).\nReturns TRUE if the line along Direction from Position hits the edge of the world in the current simulator, returns FALSE if that edge crosses into another simulator. - llBreakLink + llEjectFromLand - energy - 10.0 - sleep - 0.0 - return - void arguments - LinkNumber + AvatarID - type - integer tooltip - + + type + key + energy + 10 + return + void + sleep + 0 tooltip - De-links the prim with the given link number (requires permission PERMISSION_CHANGE_LINKS be set). + Ejects AvatarID from land that you own.\nEjects AvatarID from land that the object owner (group or resident) owns. - llCastRay + llEmail - energy - - sleep - - return - list arguments - Start + Address - type - vector tooltip - + + type + string - End + Subject - type - vector tooltip - + + type + string - Options + Text - type - list tooltip - + + type + string + energy + 10 + return + void + sleep + 20 tooltip - Casts a ray into the physics world from 'start' to 'end' and returns data according to details in Options.\nReports collision data for intersections with objects.\nReturn value: [UUID_1, {link_number_1}, hit_position_1, {hit_normal_1}, UUID_2, {link_number_2}, hit_position_2, {hit_normal_2}, ... , status_code] where {} indicates optional data. + Sends email to Address with Subject and Message.\nSends an email to Address with Subject and Message. - llCeil + llEscapeURL - energy - 10.0 - sleep - 0.0 - return - integer arguments - Value + URL - type - float tooltip - + + type + string - tooltip - Returns smallest integer value >= Value. - - llClearCameraParams - energy - 10.0 - sleep - 0.0 + 10 return - void - arguments - + string + sleep + 0 tooltip - Resets all camera parameters to default values and turns off scripted camera control. + + Returns an escaped/encoded version of url, replacing spaces with %20 etc.\nReturns the string that is the URL-escaped version of URL (replacing spaces with %20, etc.).\n + This function returns the UTF-8 encoded escape codes for selected characters. + - llClearLinkMedia + llEuler2Rot - energy - 0.0 - sleep - 0.0 - return - integer arguments - Link + Vector - type - integer tooltip - - - - - Face - + type - integer - tooltip - + vector + energy + 10 + return + rotation + sleep + 0 tooltip - Clears (deletes) the media and all parameters from the given Face on the linked prim.\nReturns an integer that is a STATUS_* flag, which details the success/failure of the operation. + Returns the rotation representation of the Euler angles.\nReturns the rotation represented by the Euler Angle. - llClearPrimMedia + llEvade - energy - 10.0 - sleep - 0.1 - return - integer arguments - Face + TargetID + tooltip + Agent or object to evade. type - integer + key + + + + Options + tooltip - Number of side to clear. + No options yet. + type + list - tooltip - Clears (deletes) the media and all parameters from the given Face.\nReturns an integer that is a STATUS_* flag which details the success/failure of the operation. - - llCloseRemoteDataChannel - energy - 10.0 - sleep - 1.0 + 10 return void + sleep + 0 + tooltip + Evade a specified target.\nCharacters will (roughly) try to hide from their pursuers if there is a good hiding spot along their fleeing path. Hiding means no direct line of sight from the head of the character (centre of the top of its physics bounding box) to the head of its pursuer and no direct path between the two on the navigation-mesh. + + llExecCharacterCmd + arguments - ChannelID + Command + tooltip + Command to send. type - key + integer + + + + Options + tooltip - + Height for CHARACTER_CMD_JUMP. + type + list + energy + 10 + return + void + sleep + 0 tooltip - Closes the specified XML-RPC channel. + Execute a character command.\nSend a command to the path system.\nCurrently only supports stopping the current path-finding operation or causing the character to jump. - llCloud + llFabs - energy - 10.0 - sleep - 0.0 - return - float arguments - Offset + Value - type - vector tooltip - + + type + float + energy + 10 + return + float + sleep + 0 tooltip - Returns the cloud density at the object's position + Offset. + Returns the positive version of Value.\nReturns the absolute value of Value. - llCollisionFilter + llFindNotecardTextCount - energy - 10.0 - sleep - 0.0 - return - void arguments - ObjectName + NotecardName + tooltip + type string - tooltip - - ObjectID + Pattern - type - key tooltip - + Regex pattern to find in the notecard text. + type + string - Accept + Options - type - integer tooltip - If TRUE, only accept collisions with ObjectName name AND ObjectID (either is optional), otherwise with objects not ObjectName AND ObjectID. + A list of options to control the search. Included for future expansion, should be [] + type + list + energy + 10 + return + key + sleep + 0 tooltip - Specify an empty string or NULL_KEY for Accept, to not filter on the corresponding parameter. + + Searches the text of a cached notecard for lines containing the given pattern and returns the + number of matches found through a dataserver event. + - llCollisionSound + llFindNotecardTextSync - energy - 10.0 - sleep - 0.0 - return - void arguments - ImpactSound + NotecardName + + tooltip + + type + string + + + + Pattern + tooltip + Regex pattern to find in the notecard text. type string + + + + StartMatch + tooltip - + The number of matches to skip before returning values. + type + integer - ImpactVolume + Count + tooltip + The maximum number of matches to return. If 0 this function will return the first 64 matches found. type - float + integer + + + + Options + tooltip - + A list of options to control the search. Included for future expansion, should be [] + type + list + energy + 10 + return + list + sleep + 0 tooltip - Suppress default collision sounds, replace default impact sounds with ImpactSound.\nThe ImpactSound must be in the object inventory.\nSupply an empty string to suppress collision sounds. + + Searches the text of a cached notecard for lines containing the given pattern. + Returns a list of line numbers and column where a match is found. If the notecard is not in + the cache it returns a list containing a single entry of NAK. If no matches are found an + empty list is returned. + - llCollisionSprite + llFleeFrom - energy - 10.0 - sleep - 0.0 - return - void arguments - ImpactSprite + Source - type - string tooltip - + Global coordinate from which to flee. + type + vector - - tooltip - Suppress default collision sprites, replace default impact sprite with ImpactSprite; found in the object inventory (empty string to just suppress). - - llCos - - energy - 10.0 - sleep - 0.0 - return - float - arguments - - Theta + Distance + tooltip + Distance in meters to flee from the source. type float - tooltip - - - tooltip - Returns the cosine of Theta (Theta in radians). - - llCreateCharacter - - energy - - sleep - - return - void - arguments - Options + tooltip + No options available at this time. type list - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Convert link-set to AI/Physics character.\nCreates a path-finding entity, known as a "character", from the object containing the script. Required to activate use of path-finding functions.\nOptions is a list of key/value pairs. + Flee from a point.\nDirects a character (llCreateCharacter) to keep away from a defined position in the region or adjacent regions. - llCreateKeyValue + llFloor - energy - 10.0 - sleep - 0.0 - return - key arguments - - Key - - type - string - tooltip - - - - - Value - type - string - tooltip - + Value + + tooltip + + type + float + - + energy + 10 + return + integer + sleep + 0 tooltip - - Starts an asychronous transaction to create a key-value pair. Will fail with XP_ERROR_STORAGE_EXCEPTION if the key already exists. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value passed to the function. - + Returns largest integer value <= Value. - llCreateLink + llForceMouselook - energy - 10.0 - sleep - 1.0 - return - void arguments - TargetPrim + Enable - type - key tooltip - Object UUID that is in the same region. - - - - Parent - + Boolean, if TRUE when an avatar sits on the prim, the avatar will be forced into mouse-look mode.\nFALSE is the default setting and will undo a previously set TRUE or do nothing. type integer - tooltip - If FALSE, then TargetPrim becomes the root. If TRUE, then the script's object becomes the root. + energy + 10 + return + void + sleep + 0 tooltip - Attempt to link the object the script is in, to target (requires permission PERMISSION_CHANGE_LINKS be set).\nRequires permission PERMISSION_CHANGE_LINKS be set. + If Enable is TRUE any avatar that sits on this object is forced into mouse-look mode.\nAfter calling this function with Enable set to TRUE, any agent sitting down on the prim will be forced into mouse-look.\nJust like llSitTarget, this changes a permanent property of the prim (not the object) and needs to be reset by calling this function with Enable set to FALSE in order to disable it. - llCSV2List + llFrand - energy - 10.0 - sleep - 0.0 - return - list arguments - Text + Magnitude - type - string tooltip - + + type + float + energy + 10 + return + float + sleep + 0 tooltip - Create a list from a string of comma separated values specified in Text. + Returns a pseudo random number in the range [0, Magnitude] or [Magnitude, 0].\nReturns a pseudo-random number between [0, Magnitude]. - llDataSizeKeyValue + llGenerateKey + arguments + energy - 10.0 - sleep - 0.0 + 10 return key - arguments - + sleep + 0 tooltip - - Starts an asychronous transaction the request the used and total amount of data allocated for the Experience. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the the amount in use and the third item will be the total available. - + Generates a key (SHA-1 hash) using UUID generation to create a unique key.\nAs the UUID produced is versioned, it should never return a value of NULL_KEY.\nThe specific UUID version is an implementation detail that has changed in the past and may change again in the future. Do not depend upon the UUID that is returned to be version 5 SHA-1 hash. - llDeleteCharacter + llGetAccel + arguments + energy - - sleep - + 10 return - void - arguments - + vector + sleep + 0 tooltip - Convert link-set from AI/Physics character to Physics object.\nConvert the current link-set back to a standard object, removing all path-finding properties. + Returns the acceleration of the object relative to the region's axes.\nGets the acceleration of the object. - llDeleteKeyValue + llGetAgentInfo - energy - 10.0 - sleep - 0.0 - return - key arguments - - Key - - type - string - tooltip - - - + + AvatarID + + tooltip + + type + key + + + energy + 10 + return + integer + sleep + 0 tooltip - Starts an asychronous transaction to delete a key-value pair. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. + Returns an integer bit-field containing the agent information about id.\n + Returns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING, AGENT_IN_AIR and/or AGENT_FLOATING_VIA_SCRIPTED_ATTACHMENT.\nReturns information about the given agent ID as a bit-field of agent info constants. - llDeleteSubList + llGetAgentLanguage - energy - 10.0 - sleep - 0.0 - return - list arguments - Source + AvatarID - type - list tooltip - + + type + key + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the language code of the preferred interface language of the avatar.\nReturns a string that is the language code of the preferred interface language of the resident. + + llGetAgentList + + arguments + - Start + Scope + tooltip + The scope (region, parcel, parcel same owner) to return agents for. type integer - tooltip - - End + Options - type - integer tooltip - + List of options to apply. Current unused. + type + list + energy + 10 + return + list + sleep + 0 tooltip - Removes the slice from start to end and returns the remainder of the list.\nRemove a slice from the list and return the remainder, start and end are inclusive.\nUsing negative numbers for start and/or end causes the index to count backwards from the length of the list, so 0, -1 would delete the entire list.\nIf Start is larger than End the list deleted is the exclusion of the entries; so 6, 4 would delete the entire list except for the 5th. list entry. + Requests a list of agents currently in the region, limited by the scope parameter.\nReturns a list [key UUID-0, key UUID-1, ..., key UUID-n] or [string error_msg] - returns avatar keys for all agents in the region limited to the area(s) specified by scope - llDeleteSubString + llGetAgentSize - energy - 10.0 - sleep - 0.0 - return - string arguments - Source + AvatarID - type - string tooltip - - - - - Start - + type - integer - tooltip - + key + + energy + 10 + return + vector + sleep + 0 + tooltip + If the avatar is in the same region, returns the size of the bounding box of the requested avatar by id, otherwise returns ZERO_VECTOR.\nIf the agent is in the same region as the object, returns the size of the avatar. + + llGetAlpha + + arguments + - End + Face + tooltip + type integer - tooltip - + energy + 10 + return + float + sleep + 0 tooltip - Removes the indicated sub-string and returns the result.\nStart and End are inclusive.\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would delete the entire string.\nIf Start is larger than End, the sub-string is the exclusion of the entries; so 6, 4 would delete the entire string except for the 5th. character. + Returns the alpha value of Face.\nReturns the 'alpha' of the given face. If face is ALL_SIDES the value returned is the mean average of all faces. - llDetachFromAvatar + llGetAndResetTime + arguments + energy - 10.0 - sleep - 0.0 + 10 return - void - arguments - + float + sleep + 0 tooltip - Remove the object containing the script from the avatar. + Returns the script time in seconds and then resets the script timer to zero.\nGets the time in seconds since starting and resets the time to zero. - llDetectedGrab + llGetAnimation - energy - 10.0 - sleep - 0.0 - return - vector arguments - Number + AvatarID - type - integer tooltip - + + type + key + energy + 10 + return + string + sleep + 0 tooltip - Returns the grab offset of a user touching the object.\nReturns <0.0, 0.0, 0.0> if Number is not a valid object. + Returns the name of the currently playing locomotion animation for the avatar id.\nReturns the currently playing animation for the specified avatar ID. - llDetectedGroup + llGetAnimationList - energy - 10.0 - sleep - 0.0 - return - integer arguments - Number + AvatarID - type - integer tooltip - + + type + key + energy + 10 + return + list + sleep + 0 tooltip - Returns TRUE if detected object or agent Number has the same user group active as this object.\nIt will return FALSE if the object or agent is in the group, but the group is not active. + Returns a list of keys of playing animations for an avatar.\nReturns a list of keys of all playing animations for the specified avatar ID. - llDetectedKey + llGetAnimationOverride - energy - 10.0 - sleep - 0.0 - return - key arguments - Number + AnimationState - type - integer tooltip - + + type + string + energy + 10 + return + string + sleep + 0 tooltip - Returns the key of detected object or avatar number.\nReturns NULL_KEY if Number is not a valid index. + Returns a string that is the name of the animation that is used for the specified animation state\nTo use this function the script must obtain either the PERMISSION_OVERRIDE_ANIMATIONS or PERMISSION_TRIGGER_ANIMATION permission (automatically granted to attached objects). - llDetectedLinkNumber + llGetAttached + arguments + energy - 10.0 - sleep - 0.0 + 10 return integer + sleep + 0 + tooltip + Returns the object's attachment point, or 0 if not attached. + + llGetAttachedList + arguments - Number + ID - type - integer tooltip - + Avatar to get attachments + type + key + energy + 10 + return + list + sleep + 0 tooltip - Returns the link position of the triggered event for touches and collisions only.\n0 for a non-linked object, 1 for the root of a linked object, 2 for the first child, etc. + Returns a list of keys of all visible (not HUD) attachments on the avatar identified by the ID argument - llDetectedName + llGetAttachedListFiltered - energy - 10.0 - sleep - 0.0 - return - string arguments - Number + AgentID + tooltip + An agent in the region. type - integer + key + + + + Options + tooltip - + A list of option for inventory transfer. + type + list + energy + 10 + return + list + sleep + 0 tooltip - Returns the name of detected object or avatar number.\nReturns the name of detected object number.\nReturns empty string if Number is not a valid index. + Retrieves a list of attachments on an avatar. - llDetectedOwner + llGetBoundingBox - energy - 10.0 - sleep - 0.0 - return - key arguments - Number + ID - type - integer tooltip - + + type + key + energy + 10 + return + list + sleep + 0 tooltip - Returns the key of detected object's owner.\nReturns invalid key if Number is not a valid index. + Returns the bounding box around the object (including any linked prims) relative to its root prim, as a list in the format [ (vector) min_corner, (vector) max_corner ]. - llDetectedPos + llGetCameraAspect + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the current camera aspect ratio (width / height) of the agent who has granted the scripted object PERMISSION_TRACK_CAMERA permissions. If no permissions have been granted: it returns zero. + + llGetCameraFOV + arguments + energy - 10.0 + 10 + return + float sleep - 0.0 + 0 + tooltip + Returns the current camera field of view of the agent who has granted the scripted object PERMISSION_TRACK_CAMERA permissions. If no permissions have been granted: it returns zero. + + llGetCameraPos + + arguments + + energy + 10 return vector - arguments - - - Number - - type - integer - tooltip - - - - + sleep + 0 tooltip - Returns the position of detected object or avatar number.\nReturns <0.0, 0.0, 0.0> if Number is not a valid index. + Returns the current camera position for the agent the task has permissions for.\nReturns the position of the camera, of the user that granted the script PERMISSION_TRACK_CAMERA. If no user has granted the permission, it returns ZERO_VECTOR. - llDetectedRot + llGetCameraRot + arguments + energy - 10.0 - sleep - 0.0 + 10 return rotation - arguments - - - Number - - type - integer - tooltip - - - - + sleep + 0 tooltip - Returns the rotation of detected object or avatar number.\nReturns <0.0, 0.0, 0.0, 1.0> if Number is not a valid offset. + Returns the current camera orientation for the agent the task has permissions for. If no user has granted the PERMISSION_TRACK_CAMERA permission, returns ZERO_ROTATION. - llDetectedTouchBinormal + llGetCenterOfMass + arguments + energy - 10.0 - sleep - 0.0 + 10 return vector + sleep + 0 + tooltip + Returns the prim's centre of mass (unless called from the root prim, where it returns the object's centre of mass). + + llGetClosestNavPoint + arguments - Index + Point - type - integer tooltip - Index of detection information + A point in region-local space. + type + vector - - tooltip - Returns the surface bi-normal for a triggered touch event.\nReturns a vector that is the surface bi-normal (tangent to the surface) where the touch event was triggered. - - llDetectedTouchFace - - energy - 10.0 - sleep - 0.0 - return - integer - arguments - - Index + Options - type - integer tooltip - Index of detection information + No options at this time. + type + list + energy + 10 + return + list + sleep + 0 tooltip - Returns the index of the face where the avatar clicked in a triggered touch event. + Get the closest navigable point to the point provided.\nThe function accepts a point in region-local space (like all the other path-finding methods) and returns either an empty list or a list containing a single vector which is the closest point on the navigation-mesh to the point provided. - llDetectedTouchNormal + llGetColor - energy - 10.0 - sleep - 0.0 - return - vector arguments - Index + Face + tooltip + type integer - tooltip - Index of detection information + energy + 10 + return + vector + sleep + 0 tooltip - Returns the surface normal for a triggered touch event.\nReturns a vector that is the surface normal (perpendicular to the surface) where the touch event was triggered. + Returns the color on Face.\nReturns the color of Face as a vector of red, green, and blue values between 0 and 1. If face is ALL_SIDES the color returned is the mean average of each channel. - llDetectedTouchPos + llGetCreator + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - - - Index - - type - integer - tooltip - Index of detected information - - - + key + sleep + 0 tooltip - Returns the position, in region coordinates, where the object was touched in a triggered touch event.\nUnless it is a HUD, in which case it returns the position relative to the attach point. + Returns a key for the creator of the prim.\nReturns the key of the object's original creator. Similar to llGetOwner. - llDetectedTouchST + llGetDate + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - - - Index - - type - integer - tooltip - Index of detection information - - - + string + sleep + 0 tooltip - Returns a vector that is the surface coordinates where the prim was touched.\nThe X and Y vector positions contain the horizontal (S) and vertical (T) face coordinates respectively.\nEach component is in the interval [0.0, 1.0].\nTOUCH_INVALID_TEXCOORD is returned if the surface coordinates cannot be determined (e.g. when the viewer does not support this function). + Returns the current date in the UTC time zone in the format YYYY-MM-DD.\nReturns the current UTC date as YYYY-MM-DD. - llDetectedTouchUV + llGetDayLength + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - - - Index - - type - integer - tooltip - Index of detection information - - - + integer + sleep + 0 tooltip - Returns a vector that is the texture coordinates for where the prim was touched.\nThe X and Y vector positions contain the U and V face coordinates respectively.\nTOUCH_INVALID_TEXCOORD is returned if the touch UV coordinates cannot be determined (e.g. when the viewer does not support this function). + Returns the number of seconds in a day on this parcel. - llDetectedType + llGetDayOffset + arguments + energy - 10.0 - sleep - 0.0 + 10 return integer + sleep + 0 + tooltip + Returns the number of seconds in a day is offset from midnight in this parcel. + + llGetDisplayName + arguments - Number + AvatarID - type - integer tooltip - + Avatar UUID that is in the same region, or is otherwise known to the region. + type + key + energy + 10 + return + string + sleep + 0 tooltip - Returns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object.\nReturns 0 if number is not a valid index.\nNote that number is a bit-field, so comparisons need to be a bitwise checked. e.g.:\ninteger iType = llDetectedType(0);\n{\n // ...do stuff with the agent\n} + Returns the display name of an avatar, if the avatar is connected to the current region, or if the name has been cached. Otherwise, returns an empty string. Use llRequestDisplayName if the avatar may be absent from the region. - llDetectedVel + llGetEnergy + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector + float + sleep + 0 + tooltip + Returns how much energy is in the object as a percentage of maximum. + + llGetEnv + arguments - Number + DataRequest - type - integer tooltip - + The type of data to request. Any other string will cause an empty string to be returned. + type + string + energy + 10 + return + string + sleep + 0 tooltip - Returns the velocity of the detected object Number.\nReturns<0.0, 0.0, 0.0> if Number is not a valid offset. + Returns a string with the requested data about the region. - llDialog + llGetEnvironment - energy - 10.0 - sleep - 0.1 - return - void arguments - AvatarID + Position - type - key tooltip - - - - - Text - + Location within the region. type - string - tooltip - + vector - Buttons + EnvParams - type - list tooltip - - - - - Channel - + List of environment settings requested for the specified parcel location. type - integer - tooltip - + list - tooltip - Shows a dialog box on the avatar's screen with the message.\n - Up to 12 strings in the list form buttons.\n - If a button is clicked, the name is chatted on Channel.\nOpens a "notify box" in the given avatars screen displaying the message.\n - Up to twelve buttons can be specified in a list of strings. When the user clicks a button, the name of the button is said on the specified channel.\n - Channels work just like llSay(), so channel 0 can be heard by everyone.\n - The chat originates at the object's position, not the avatar's position, even though it is said as the avatar (uses avatar's UUID and Name etc.).\n - Examples:\n - llDialog(who, "Are you a boy or a girl?", [ "Boy", "Girl" ], -4913);\n - llDialog(who, "This shows only an OK button.", [], -192);\n - llDialog(who, "This chats so you can 'hear' it.", ["Hooray"], 0); - - llDie - energy - 0.0 - sleep - 0.0 + 10 return - void - arguments - + list + sleep + 0 tooltip - Delete the object which holds the script. + Returns a string with the requested data about the region. - llDumpList2String + llGetExperienceDetails - energy - 10.0 - sleep - 0.0 - return - string arguments - Source + ExperienceID - type - list tooltip - - - - - Separator - + May be NULL_KEY to retrieve the details for the script's Experience type - string - tooltip - + key + energy + 10 + return + list + sleep + 0 tooltip - Returns the list as a single string, using Separator between the entries.\nWrite the list out as a single string, using Separator between values. + + Returns a list with the following Experience properties: [Experience Name, Owner ID, Group ID, Experience ID, State, State Message]. State is an integer corresponding to one of the constants XP_ERROR_... and State Message is the string returned by llGetExperienceErrorMessage for that integer. + - llEdgeOfWorld + llGetExperienceErrorMessage - energy - 10.0 - sleep - 0.0 - return - integer arguments - Position + Error - type - vector tooltip - - - - - Direction - + An Experience error code to translate. type - vector - tooltip - + integer + energy + 10 + return + string + sleep + 0 tooltip - Checks to see whether the border hit by Direction from Position is the edge of the world (has no neighboring region).\nReturns TRUE if the line along Direction from Position hits the edge of the world in the current simulator, returns FALSE if that edge crosses into another simulator. + + Returns a string describing the error code passed or the string corresponding with XP_ERROR_UNKNOWN_ERROR if the value is not a valid Experience error code. + - llEjectFromLand + llGetForce + arguments + energy - 10.0 + 10 + return + vector sleep - 0.0 + 0 + tooltip + Returns the force (if the script is physical).\nReturns the current force if the script is physical. + + llGetFreeMemory + + arguments + + energy + 10 return - void + integer + sleep + 0 + tooltip + Returns the number of free bytes of memory the script can use.\nReturns the available free space for the current script. This is inaccurate with LSO. + + llGetFreeURLs + arguments - - - AvatarID - - type - key - tooltip - - - - + + energy + 10 + return + integer + sleep + 0 tooltip - Ejects AvatarID from land that you own.\nEjects AvatarID from land that the object owner (group or resident) owns. + Returns the number of available URLs for the current script.\nReturns an integer that is the number of available URLs. - llEmail + llGetGMTclock + arguments + energy - 10.0 + 10 + return + float sleep - 20.0 + 0 + tooltip + Returns the time in seconds since midnight GMT.\nGets the time in seconds since midnight in GMT/UTC. + + llGetGeometricCenter + + arguments + + energy + 10 return - void + vector + sleep + 0 + tooltip + Returns the vector that is the geometric center of the object relative to the root prim. + + llGetHTTPHeader + arguments - Address + HTTPRequestID - type - string tooltip - - - - - Subject - + A valid HTTP request key type - string - tooltip - + key - Text + Header + tooltip + Header value name type string - tooltip - - tooltip - Sends email to Address with Subject and Message.\nSends an email to Address with Subject and Message. - - llEscapeURL - energy - 10.0 - sleep - 0.0 + 10 return string + sleep + 0 + tooltip + Returns the value for header for request_id.\nReturns a string that is the value of the Header for HTTPRequestID. + + llGetHealth + arguments - URL + ID - type - string tooltip - + The ID of an agent or object in the region. + type + key + energy + 10 + return + float + sleep + 0 tooltip - Returns an escaped/encoded version of url, replacing spaces with %20 etc.\nReturns the string that is the URL-escaped version of URL (replacing spaces with %20, etc.).\n - This function returns the UTF-8 encoded escape codes for selected characters. + Returns the current health of an avatar or object in the region. - llEuler2Rot + llGetInventoryAcquireTime - energy - 10.0 - sleep - 0.0 - return - rotation arguments - Vector + InventoryItem - type - vector tooltip - + Name of item in prim inventory. + type + string + energy + 10 + return + string + sleep + 0 tooltip - Returns the rotation representation of the Euler angles.\nReturns the rotation represented by the Euler Angle. + Returns the time at which the item was placed into this prim's inventory as a timestamp. - llEvade + llGetInventoryCreator - energy - - sleep - - return - void arguments - TargetID + InventoryItem - type - key tooltip - Agent or object to evade. - - - - Options - + type - list - tooltip - No options yet. + string + energy + 10 + return + key + sleep + 0 tooltip - Evade a specified target.\nCharacters will (roughly) try to hide from their pursuers if there is a good hiding spot along their fleeing path. Hiding means no direct line of sight from the head of the character (centre of the top of its physics bounding box) to the head of its pursuer and no direct path between the two on the navigation-mesh. + Returns a key for the creator of the inventory item.\nThis function returns the UUID of the creator of item. If item is not found in inventory, the object says "No item named 'name'". - llExecCharacterCmd + llGetInventoryDesc - energy - - sleep - - return - void arguments - Command + InventoryItem - type - integer tooltip - Command to send. - - - - Options - + type - list - tooltip - Height for CHARACTER_CMD_JUMP. + string + energy + 10 + return + string + sleep + 0 tooltip - Execute a character command.\nSend a command to the path system.\nCurrently only supports stopping the current path-finding operation or causing the character to jump. + Returns the item description of the item in inventory. If item is not found in inventory, the object says "No item named 'name'" to the debug channel and returns an empty string. - llFabs + llGetInventoryKey - energy - 10.0 - sleep - 0.0 - return - float arguments - Value + InventoryItem - type - float tooltip - + + type + string + energy + 10 + return + key + sleep + 0 tooltip - Returns the positive version of Value.\nReturns the absolute value of Value. + Returns the key that is the UUID of the inventory named.\nReturns the key of the inventory named. - llFleeFrom + llGetInventoryName - energy - - sleep - - return - void arguments - Source + InventoryType - type - vector tooltip - Global coordinate from which to flee. - - - - Distance - + Inventory item type type - float - tooltip - Distance in meters to flee from the source. + integer - Options + Index - type - list tooltip - No options available at this time. + Index number of inventory item. + type + integer + energy + 10 + return + string + sleep + 0 tooltip - Flee from a point.\nDirects a character (llCreateCharacter) to keep away from a defined position in the region or adjacent regions. + Returns the name of the inventory item of a given type, specified by index number.\nUse the inventory constants INVENTORY_* to specify the type. - llFloor + llGetInventoryNumber - energy - 10.0 - sleep - 0.0 - return - integer arguments - Value + InventoryType - type - float tooltip - + Inventory item type + type + integer + energy + 10 + return + integer + sleep + 0 tooltip - Returns largest integer value <= Value. + Returns the quantity of items of a given type (INVENTORY_* flag) in the prim's inventory.\nUse the inventory constants INVENTORY_* to specify the type. - llForceMouselook + llGetInventoryPermMask - energy - 10.0 - sleep - 0.0 - return - void arguments - Enable + InventoryItem + tooltip + Inventory item name. type - integer + string + + + + BitMask + tooltip - Boolean, if TRUE when an avatar sits on the prim, the avatar will be forced into mouse-look mode.\nFALSE is the default setting and will undo a previously set TRUE or do nothing. + MASK_BASE, MASK_OWNER, MASK_GROUP, MASK_EVERYONE or MASK_NEXT + type + integer + energy + 10 + return + integer + sleep + 0 tooltip - If Enable is TRUE any avatar that sits on this object is forced into mouse-look mode.\nAfter calling this function with Enable set to TRUE, any agent sitting down on the prim will be forced into mouse-look.\nJust like llSitTarget, this changes a permanent property of the prim (not the object) and needs to be reset by calling this function with Enable set to FALSE in order to disable it. + Returns the requested permission mask for the inventory item.\nReturns the requested permission mask for the inventory item defined by InventoryItem. If item is not in the object's inventory, llGetInventoryPermMask returns FALSE and causes the object to say "No item named '<item>'", where "<item>" is item. - llFrand + llGetInventoryType - energy - 10.0 - sleep - 0.0 - return - float arguments - Magnitude + InventoryItem - type - float tooltip - + + type + string - tooltip - Returns a pseudo random number in the range [0, Magnitude] or [Magnitude, 0].\nReturns a pseudo-random number between [0, Magnitude]. - - llGenerateKey - energy - 0 + 10 + return + integer sleep 0 - return - key - arguments - tooltip - Generates a key (SHA-1 hash) using UUID generation to create a unique key.\nAs the UUID produced is versioned, it should never return a value of NULL_KEY.\nThe specific UUID version is an implementation detail that has changed in the past and may change again in the future. Do not depend upon the UUID that is returned to be version 5 SHA-1 hash. + Returns the type of the named inventory item.\nLike all inventory functions, llGetInventoryType is case-sensitive. - llGetAccel + llGetKey + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - + key + sleep + 0 tooltip - Returns the acceleration of the object relative to the region's axes.\nGets the acceleration of the object. + Returns the key of the prim the script is attached to.\nGet the key for the object which has this script. - llGetAgentInfo + llGetLandOwnerAt - energy - 10.0 - sleep - 0.0 - return - integer arguments - AvatarID + Position - type - key tooltip - + + type + vector + energy + 10 + return + key + sleep + 0 tooltip - Returns an integer bit-field containing the agent information about id.\n - Returns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING and/or AGENT_IN_AIR.\nReturns information about the given agent ID as a bit-field of agent info constants. + Returns the key of the land owner, returns NULL_KEY if public.\nReturns the key of the land owner at Position, or NULL_KEY if public. - llGetAgentLanguage + llGetLinkKey - energy - 10.0 - sleep - 0.0 - return - string arguments - AvatarID + LinkNumber - type - key tooltip - + + type + integer + energy + 10 + return + key + sleep + 0 tooltip - Returns the language code of the preferred interface language of the avatar.\nReturns a string that is the language code of the preferred interface language of the resident. + Returns the key of the linked prim LinkNumber.\nReturns the key of LinkNumber in the link set. - llGetAgentList + llGetLinkMedia - energy - 10.0 - sleep - 0.0 - return - list arguments - Scope + LinkNumber + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag type integer - tooltip - The scope (region, parcel, parcel same owner) to return agents for. - Options + Face - type - list tooltip - List of options to apply. Current unused. + The prim's side number + type + integer - - tooltip - Requests a list of agents currently in the region, limited by the scope parameter.\nReturns a list [key UUID-0, key UUID-1, ..., key UUID-n] or [string error_msg] - returns avatar keys for all agents in the region limited to the area(s) specified by scope - - llGetAgentSize - - energy - 10.0 - sleep - 0.0 - return - vector - arguments - - AvatarID + Parameters - type - key tooltip - + A list of PRIM_* property constants to return values of. + type + list + energy + 10 + return + list + sleep + 0 tooltip - If the avatar is in the same region, returns the size of the bounding box of the requested avatar by id, otherwise returns ZERO_VECTOR.\nIf the agent is in the same region as the object, returns the size of the avatar. + Get the media parameters for a particular face on linked prim, given the desired list of parameter names. Returns a list of values in the order requested. Returns an empty list if no media exists on the face. - llGetAlpha + llGetLinkName - energy - 10.0 - sleep - 0.0 - return - float arguments - Face + LinkNumber + tooltip + type integer - tooltip - + energy + 10 + return + string + sleep + 0 tooltip - Returns the alpha value of Face.\nReturns the 'alpha' of the given face. If face is ALL_SIDES the value returned is the mean average of all faces. + Returns the name of LinkNumber in a link set.\nReturns the name of LinkNumber the link set. - llGetAndResetTime + llGetLinkNumber + arguments + energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - + integer + sleep + 0 tooltip - Returns the script time in seconds and then resets the script timer to zero.\nGets the time in seconds since starting and resets the time to zero. + Returns the link number of the prim containing the script (0 means not linked, 1 the prim is the root, 2 the prim is the first child, etc.).\nReturns the link number of the prim containing the script. 0 means no link, 1 the root, 2 for first child, etc. - llGetAnimation + llGetLinkNumberOfSides - energy - 10.0 - sleep - 0.0 - return - string arguments - AvatarID + LinkNumber - type - key tooltip - + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + energy + 10 + return + integer + sleep + 0 tooltip - Returns the name of the currently playing locomotion animation for the avatar id.\nReturns the currently playing animation for the specified avatar ID. + Returns the number of sides of the specified linked prim.\nReturns an integer that is the number of faces (or sides) of the prim link. - llGetAnimationList + llGetLinkPrimitiveParams - energy - 10.0 - sleep - 0.0 - return - list arguments - AvatarID + LinkNumber + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. type - key + integer + + + + Parameters + tooltip - + PRIM_* flags. + type + list - tooltip - Returns a list of keys of playing animations for an avatar.\nReturns a list of keys of all playing animations for the specified avatar ID. - - llGetAnimationOverride - energy - 0 + 10 + return + list sleep 0 - return - string + tooltip + Returns the list of primitive attributes requested in the Parameters list for LinkNumber.\nPRIM_* flags can be broken into three categories, face flags, prim flags, and object flags.\n* Supplying a prim or object flag will return that flags attributes.\n* Face flags require the user to also supply a face index parameter. + + llGetLinkSitFlags + arguments - AnimationState + LinkNumber - type - string tooltip - + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer - - tooltip - Returns a string that is the name of the animation that is used for the specified animation state\nTo use this function the script must obtain either the PERMISSION_OVERRIDE_ANIMATIONS or PERMISSION_TRIGGER_ANIMATION permission (automatically granted to attached objects). - - llGetAttached - + energy - 10.0 - sleep - 0.0 + 10 return integer - arguments - + sleep + 0 tooltip - Returns the object's attachment point, or 0 if not attached. + Returns the sit flags set on the specified prim in a linkset. - llGetAttachedList + llGetListEntryType - energy - 10.0 - sleep - 0.0 - return - list arguments - ID + ListVariable + tooltip + type - key + list + + + + Index + tooltip - Avatar to get attachments + + type + integer + energy + 10 + return + integer + sleep + 0 tooltip - Returns a list of keys of all visible (not HUD) attachments on the avatar identified by the ID argument + Returns the type of the index entry in the list (TYPE_INTEGER, TYPE_FLOAT, TYPE_STRING, TYPE_KEY, TYPE_VECTOR, TYPE_ROTATION, or TYPE_INVALID if index is off list).\nReturns the type of the variable at Index in ListVariable. - llGetBoundingBox + llGetListLength - energy - 10.0 - sleep - 0.0 - return - list arguments - ID + ListVariable - type - key tooltip - + + type + list + energy + 10 + return + integer + sleep + 0 tooltip - Returns the bounding box around the object (including any linked prims) relative to its root prim, as a list in the format [ (vector) min_corner, (vector) max_corner ]. + Returns the number of elements in the list.\nReturns the number of elements in ListVariable. - llGetCameraPos + llGetLocalPos + arguments + energy - 10.0 - sleep - 0.0 + 10 return vector - arguments - + sleep + 0 tooltip - Returns the current camera position for the agent the task has permissions for.\nReturns the position of the camera, of the user that granted the script PERMISSION_TRACK_CAMERA. If no user has granted the permission, it returns ZERO_VECTOR. + Returns the position relative to the root.\nReturns the local position of a child object relative to the root. - llGetCameraRot + llGetLocalRot + arguments + energy - 10.0 - sleep - 0.0 + 10 return rotation - arguments - + sleep + 0 tooltip - Returns the current camera orientation for the agent the task has permissions for. If no user has granted the PERMISSION_TRACK_CAMERA permission, returns ZERO_ROTATION. + Returns the rotation local to the root.\nReturns the local rotation of a child object relative to the root. - llGetCenterOfMass + llGetMass + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - + float + sleep + 0 tooltip - Returns the prim's centre of mass (unless called from the root prim, where it returns the object's centre of mass). + Returns the mass of object that the script is attached to.\nReturns the scripted object's mass. When called from a script in a link-set, the parent will return the sum of the link-set weights, while a child will return just its own mass. When called from a script inside an attachment, this function will return the mass of the avatar it's attached to, not its own. - llGetClosestNavPoint + llGetMassMKS + arguments + energy - - sleep - + 10 return - list - arguments - - - Point - - type - vector - tooltip - A point in region-local space. - - - - Options - - type - list - tooltip - No options at this time. - - - + float + sleep + 0 tooltip - Get the closest navigable point to the point provided.\nThe function accepts a point in region-local space (like all the other path-finding methods) and returns either an empty list or a list containing a single vector which is the closest point on the navigation-mesh to the point provided. + Acts as llGetMass(), except that the units of the value returned are Kg. - llGetColor + llGetMaxScaleFactor + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - - - Face - - type - integer - tooltip - - - - + float + sleep + 0 tooltip - Returns the color on Face.\nReturns the color of Face as a vector of red, green, and blue values between 0 and 1. If face is ALL_SIDES the color returned is the mean average of each channel. + Returns the largest multiplicative uniform scale factor that can be successfully applied (via llScaleByFactor()) to the object without violating prim size or linkability rules. - llGetCreator + llGetMemoryLimit + arguments + energy - 10.0 - sleep - 0.0 + 10 return - key - arguments - + integer + sleep + 0 tooltip - Returns a key for the creator of the prim.\nReturns the key of the object's original creator. Similar to llGetOwner. + Get the maximum memory a script can use, in bytes. - llGetDate + llGetMinScaleFactor + arguments + energy - 10.0 - sleep - 0.0 + 10 return - string - arguments - + float + sleep + 0 tooltip - Returns the current date in the UTC time zone in the format YYYY-MM-DD.\nReturns the current UTC date as YYYY-MM-DD. + Returns the smallest multiplicative uniform scale factor that can be successfully applied (via llScaleByFactor()) to the object without violating prim size or linkability rules. - llGetDisplayName + llGetMoonDirection + arguments + energy - 10.0 + 10 + return + vector sleep - 0.0 + 0 + tooltip + Returns a normalized vector of the direction of the moon in the parcel.\nReturns the moon's direction on the simulator in the parcel. + + llGetMoonRotation + + arguments + + energy + 10 return - string + rotation + sleep + 0 + tooltip + Returns the rotation applied to the moon in the parcel. + + llGetNextEmail + arguments - AvatarID + Address + tooltip + type - key + string + + + + Subject + tooltip - Avatar UUID that is in the same region, or is otherwise known to the region. + + type + string - tooltip - Returns the display name of an avatar, if the avatar is connected to the current region, or if the name has been cached. Otherwise, returns an empty string. Use llRequestDisplayName if the avatar may be absent from the region. - - llGetEnergy - energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - + void + sleep + 0 tooltip - Returns how much energy is in the object as a percentage of maximum. + Fetch the next queued email with that matches the given address and/or subject, via the email event.\nIf the parameters are blank, they are not used for filtering. - llGetEnv + llGetNotecardLine - energy - 10.0 - sleep - 0.0 - return - string arguments - DataRequest + NotecardName + tooltip + type string + + + + LineNumber + tooltip - The type of data to request. Any other string will cause an empty string to be returned. + + type + integer + energy + 10 + return + key + sleep + 0.1000000000000000055511151 tooltip - Returns a string with the requested data about the region. + Returns LineNumber from NotecardName via the dataserver event. The line index starts at zero.\nIf the requested line is passed the end of the note-card the dataserver event will return the constant EOF string.\nThe key returned by this function is a unique identifier which will be supplied to the dataserver event in the requested parameter. - llGetExperienceDetails + llGetNotecardLineSync - energy - 10.0 - sleep - 0.0 - return - list arguments - - ExperienceID - - type - key - tooltip - May be NULL_KEY to retrieve the details for the script's Experience - - + + NotecardName + + tooltip + + type + string + + + + LineNumber + + tooltip + + type + integer + + - tooltip - - Returns a list with the following Experience properties: [Experience Name, Owner ID, Group ID, Experience ID, State, State Message]. State is an integer corresponding to one of the constants XP_ERROR_... and State Message is the string returned by llGetExperienceErrorMessage for that integer. - - - llGetExperienceErrorMessage - energy - 10.0 - sleep - 0.0 + 10 return string - arguments - - - Error - - type - integer - tooltip - An Experience error code to translate. - - - - tooltip - - Returns a string describing the error code passed or the string corresponding with XP_ERROR_UNKNOWN_ERROR if the value is not a valid Experience error code. - + sleep + 0 + tooltip + Returns LineNumber from NotecardName. The line index starts at zero.\nIf the requested line is past the end of the note-card the return value will be set to the constant EOF string.\nIf the note-card is not cached on the simulator the return value is the NAK string. - llGetForce + llGetNumberOfNotecardLines + arguments + + + NotecardName + + tooltip + + type + string + + + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - + key + sleep + 0.1000000000000000055511151 tooltip - Returns the force (if the script is physical).\nReturns the current force if the script is physical. + Returns the number of lines contained within a notecard via the dataserver event.\nThe key returned by this function is a query ID for identifying the dataserver reply. - llGetFreeMemory + llGetNumberOfPrims + arguments + energy - 10.0 - sleep - 0.0 + 10 return integer - arguments - + sleep + 0 tooltip - Returns the number of free bytes of memory the script can use.\nReturns the available free space for the current script. This is inaccurate with LSO. + Returns the number of prims in a link set the script is attached to.\nReturns the number of prims in (and avatars seated on) the object the script is in. - llGetFreeURLs + llGetNumberOfSides + arguments + energy - 10.0 - sleep - 0.0 + 10 return integer - arguments - + sleep + 0 tooltip - Returns the number of available URLs for the current script.\nReturns an integer that is the number of available URLs. + Returns the number of faces (or sides) of the prim.\nReturns the number of sides of the prim which has the script. - llGetGeometricCenter + llGetObjectAnimationNames + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - + list + sleep + 0 tooltip - Returns the vector that is the geometric center of the object relative to the root prim. + Returns a list of names of playing animations for an object.\nReturns a list of names of all playing animations for the current object. - llGetGMTclock + llGetObjectDesc + arguments + energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - + string + sleep + 0 tooltip - Returns the time in seconds since midnight GMT.\nGets the time in seconds since midnight in GMT/UTC. + Returns the description of the prim the script is attached to.\nReturns the description of the scripted object/prim. You can set the description using llSetObjectDesc. - llGetHTTPHeader + llGetObjectDetails - energy - 10.0 - sleep - 0.0 - return - string arguments - HTTPRequestID + ID + tooltip + Prim or avatar UUID that is in the same region. type key - tooltip - A valid HTTP request key - Header + Parameters - type - string tooltip - Header value name + List of OBJECT_* flags. + type + list + energy + 10 + return + list + sleep + 0 tooltip - Returns the value for header for request_id.\nReturns a string that is the value of the Header for HTTPRequestID. + Returns a list of object details specified in the Parameters list for the object or avatar in the region with key ID.\nParameters are specified by the OBJECT_* constants. - llGetInventoryCreator + llGetObjectLinkKey - energy - 10.0 - sleep - 0.0 - return - key arguments - InventoryItem + id + tooltip + UUID of prim type - string + key + + + + link_no + tooltip - + Link number to retrieve + type + integer - tooltip - Returns a key for the creator of the inventory item.\nThis function returns the UUID of the creator of item. If item is not found in inventory, the object says "No item named 'name'". - - llGetInventoryKey - energy - 10.0 - sleep - 0.0 + 10 return key + sleep + 0 + tooltip + Returns the key of the linked prim link_no in a linkset.\nReturns the key of link_no in the link set specified by id. + + llGetObjectMass + arguments - InventoryItem + ID - type - string tooltip - + + type + key + energy + 10 + return + float + sleep + 0 tooltip - Returns the key that is the UUID of the inventory named.\nReturns the key of the inventory named. + Returns the mass of the avatar or object in the region.\nGets the mass of the object or avatar corresponding to ID. - llGetInventoryName + llGetObjectName + arguments + energy - 10.0 - sleep - 0.0 + 10 return string + sleep + 0 + tooltip + Returns the name of the prim which the script is attached to.\nReturns the name of the prim (not object) which contains the script. + + llGetObjectPermMask + arguments - InventoryType + Category - type - integer tooltip - Inventory item type - - - - Index - + Category is one of MASK_BASE, MASK_OWNER, MASK_GROUP, MASK_EVERYONE, or MASK_NEXT type integer - tooltip - Index number of inventory item. - tooltip - Returns the name of the inventory item of a given type, specified by index number.\nUse the inventory constants INVENTORY_* to specify the type. - - llGetInventoryNumber - energy - 10.0 - sleep - 0.0 + 10 return integer + sleep + 0 + tooltip + Returns the permission mask of the requested category for the object. + + llGetObjectPrimCount + arguments - InventoryType + ObjectID - type - integer tooltip - Inventory item type + + type + key + energy + 10 + return + integer + sleep + 0 tooltip - Returns the quantity of items of a given type (INVENTORY_* flag) in the prim's inventory.\nUse the inventory constants INVENTORY_* to specify the type. + Returns the total number of prims for an object in the region.\nReturns the prim count for any object id in the same region. - llGetInventoryPermMask + llGetOmega + arguments + energy - 10.0 + 10 + return + vector sleep - 0.0 + 0 + tooltip + Returns the rotation velocity in radians per second.\nReturns a vector that is the rotation velocity of the object in radians per second. + + llGetOwner + + arguments + + energy + 10 return - integer + key + sleep + 0 + tooltip + Returns the object owner's UUID.\nReturns the key for the owner of the object. + + llGetOwnerKey + arguments - InventoryItem + ObjectID - type - string tooltip - Inventory item name. - - - - BitMask - + type - integer - tooltip - MASK_BASE, MASK_OWNER, MASK_GROUP, MASK_EVERYONE or MASK_NEXT + key + energy + 10 + return + key + sleep + 0 tooltip - Returns the requested permission mask for the inventory item.\nReturns the requested permission mask for the inventory item defined by InventoryItem. If item is not in the object's inventory, llGetInventoryPermMask returns FALSE and causes the object to say "No item named '<item>'", where "<item>" is item. + Returns the owner of ObjectID.\nReturns the key for the owner of object ObjectID. - llGetInventoryType + llGetParcelDetails - energy - 10.0 - sleep - 0.0 - return - integer arguments - InventoryItem + Position + tooltip + Location within the region. type - string + vector + + + + ParcelDetails + tooltip - + List of details requested for the specified parcel location. + type + list - tooltip - Returns the type of the named inventory item.\nLike all inventory functions, llGetInventoryType is case-sensitive. - - llGetKey - energy - 10.0 - sleep - 0.0 + 10 return - key - arguments - + list + sleep + 0 tooltip - Returns the key of the prim the script is attached to.\nGet the key for the object which has this script. + Returns a list of parcel details specified in the ParcelDetails list for the parcel at Position.\nParameters is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA, _ID, _SEE_AVATARS.\nReturns a list that is the parcel details specified in ParcelDetails (in the same order) for the parcel at Position. - llGetLandOwnerAt - - energy - 10.0 - sleep - 0.0 - return - key + llGetParcelFlags + arguments Position + tooltip + type vector - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip - Returns the key of the land owner, returns NULL_KEY if public.\nReturns the key of the land owner at Position, or NULL_KEY if public. + Returns a mask of the parcel flags (PARCEL_FLAG_*) for the parcel that includes the point Position.\nReturns a bit-field specifying the parcel flags (PARCEL_FLAG_*) for the parcel at Position. - llGetLinkKey + llGetParcelMaxPrims - energy - 10.0 - sleep - 0.0 - return - key arguments - LinkNumber + Position + tooltip + Region coordinates (z is ignored) of parcel. type - integer + vector + + + + SimWide + tooltip - + Boolean. If FALSE then the return is the maximum prims supported by the parcel. If TRUE then it is the combined number of prims on all parcels in the region owned by the specified parcel's owner. + type + integer + energy + 10 + return + integer + sleep + 0 tooltip - Returns the key of the linked prim LinkNumber.\nReturns the key of LinkNumber in the link set. + Returns the maximum number of prims allowed on the parcel at Position for a given scope.\nThe scope may be set to an individual parcel or the combined resources of all parcels with the same ownership in the region. - llGetLinkMedia + llGetParcelMusicURL + arguments + energy - 0.0 - sleep - 0.0 + 10 return - list + string + sleep + 0 + tooltip + Gets the streaming audio URL for the parcel object is on.\nThe object owner, avatar or group, must also be the land owner. + + llGetParcelPrimCount + arguments - LinkNumber + Position - type - integer tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + Region coordinates of parcel to query. + type + vector - Face + Category + tooltip + A PARCEL_COUNT_* flag. type integer - tooltip - The prim's side number - Parameters + SimWide - type - list tooltip - A list of PRIM_* property constants to return values of. + Boolean. If FALSE then the return is the maximum prims supported by the parcel. If TRUE then it is the combined number of prims on all parcels in the region owned by the specified parcel's owner. + type + integer + energy + 10 + return + integer + sleep + 0 tooltip - Get the media parameters for a particular face on linked prim, given the desired list of parameter names. Returns a list of values in the order requested. Returns an empty list if no media exists on the face. + Returns the number of prims on the parcel at Position of the given category.\nCategories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP.\nReturns the number of prims used on the parcel at Position which are in Category.\nIf SimWide is TRUE, it returns the total number of objects for all parcels with matching ownership in the category specified.\nIf SimWide is FALSE, it returns the number of objects on this specific parcel in the category specified - llGetLinkName + llGetParcelPrimOwners - energy - 10.0 - sleep - 0.0 - return - string arguments - LinkNumber + Position - type - integer tooltip - + + type + vector + energy + 10 + return + list + sleep + 2 tooltip - Returns the name of LinkNumber in a link set.\nReturns the name of LinkNumber the link set. + Returns a list of up to 100 residents who own objects on the parcel at Position, with per-owner land impact totals.\nRequires owner-like permissions for the parcel, and for the script owner to be present in the region.\nThe list is formatted as [ key agentKey1, integer agentLI1, key agentKey2, integer agentLI2, ... ], sorted by agent key.\nThe integers are the combined land impacts of the objects owned by the corresponding agents. - llGetLinkNumber + llGetPermissions + arguments + energy - 10.0 - sleep - 0.0 + 10 return integer - arguments - + sleep + 0 tooltip - Returns the link number of the prim containing the script (0 means not linked, 1 the prim is the root, 2 the prim is the first child, etc.).\nReturns the link number of the prim containing the script. 0 means no link, 1 the root, 2 for first child, etc. + Returns an integer bitmask of the permissions that have been granted to the script. Individual permissions can be determined using a bit-wise "and" operation against the PERMISSION_* constants - llGetLinkNumberOfSides + llGetPermissionsKey + arguments + energy - 10.0 - sleep - 0.0 + 10 return - integer - arguments - - - LinkNumber - - type - integer - tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. - - - + key + sleep + 0 tooltip - Returns the number of sides of the specified linked prim.\nReturns an integer that is the number of faces (or sides) of the prim link. + Returns the key of the avatar that last granted or declined permissions to the script.\nReturns NULL_KEY if permissions were never granted or declined. - llGetLinkPrimitiveParams + llGetPhysicsMaterial + arguments + energy - 10.0 - sleep - 0.0 + 10 return list + sleep + 0 + tooltip + Returns a list of the form [float gravity_multiplier, float restitution, float friction, float density]. + + llGetPos + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the position of the task in region coordinates.\nReturns the vector position of the task in region coordinates. + + llGetPrimMediaParams + arguments - LinkNumber + Face + tooltip + face number type integer - tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. Parameters + tooltip + One or more PRIM_MEDIA_* flags type list - tooltip - PRIM_* flags. + energy + 10 + return + list + sleep + 1 tooltip - Returns the list of primitive attributes requested in the Parameters list for LinkNumber.\nPRIM_* flags can be broken into three categories, face flags, prim flags, and object flags.\n* Supplying a prim or object flag will return that flags attributes.\n* Face flags require the user to also supply a face index parameter. + Returns the media parameters for a particular face on an object, given the desired list of parameter names, in the order requested. Returns an empty list if no media exists on the face. - llGetListEntryType + llGetPrimitiveParams - energy - 10.0 - sleep - 0.0 - return - integer arguments - ListVariable + Parameters - type - list tooltip - - - - - Index - + PRIM_* flags and face parameters type - integer - tooltip - + list + energy + 10 + return + list + sleep + 0.2000000000000000111022302 tooltip - Returns the type of the index entry in the list (TYPE_INTEGER, TYPE_FLOAT, TYPE_STRING, TYPE_KEY, TYPE_VECTOR, TYPE_ROTATION, or TYPE_INVALID if index is off list).\nReturns the type of the variable at Index in ListVariable. + Returns the primitive parameters specified in the parameters list.\nReturns primitive parameters specified in the Parameters list. - llGetListLength + llGetRegionAgentCount + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of avatars in the region.\nReturns an integer that is the number of avatars in the region. + + llGetRegionCorner + arguments + energy - 10.0 + 10 + return + vector sleep - 0.0 + 0 + tooltip + Returns a vector, in meters, that is the global location of the south-west corner of the region which the object is in.\nReturns the Region-Corner of the simulator containing the task. The region-corner is a vector (values in meters) representing distance from the first region. + + llGetRegionDayLength + + arguments + + energy + 10 return integer + sleep + 0 + tooltip + Returns the number of seconds in a day in this region. + + llGetRegionDayOffset + arguments - - - ListVariable - - type - list - tooltip - - - - + + energy + 10 + return + integer + sleep + 0 tooltip - Returns the number of elements in the list.\nReturns the number of elements in ListVariable. + Returns the number of seconds in a day is offset from midnight in this parcel. - llGetLocalPos + llGetRegionFPS + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the mean region frames per second. + + llGetRegionFlags + arguments + energy - 10.0 + 10 + return + integer sleep - 0.0 + 0 + tooltip + Returns the region flags (REGION_FLAG_*) for the region the object is in.\nReturns a bit-field specifying the region flags (REGION_FLAG_*) for the region the object is in. + + llGetRegionMoonDirection + + arguments + + energy + 10 return vector - arguments - + sleep + 0 tooltip - Returns the position relative to the root.\nReturns the local position of a child object relative to the root. + Returns a normalized vector of the direction of the moon in the region.\nReturns the moon's direction on the simulator. - llGetLocalRot + llGetRegionMoonRotation + arguments + energy - 10.0 - sleep - 0.0 + 10 return rotation - arguments - + sleep + 0 tooltip - Returns the rotation local to the root.\nReturns the local rotation of a child object relative to the root. + Returns the rotation applied to the moon in the region. - llGetMass + llGetRegionName + arguments + energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - + string + sleep + 0 tooltip - Returns the mass of object that the script is attached to.\nReturns the scripted object's mass. When called from a script in a link-set, the parent will return the sum of the link-set weights, while a child will return just its own mass. When called from a script inside an attachment, this function will return the mass of the avatar it's attached to, not its own. + Returns the current region name. - llGetMassMKS + llGetRegionSunDirection + arguments + energy - - sleep - 0.0 + 10 return - float - arguments - + vector + sleep + 0 tooltip - Acts as llGetMass(), except that the units of the value returned are Kg. + Returns a normalized vector of the direction of the sun in the region.\nReturns the sun's direction on the simulator. - llGetMaxScaleFactor + llGetRegionSunRotation + arguments + energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - + rotation + sleep + 0 tooltip - Returns a float that is the largest scaling factor that can be used with llScaleByFactor to resize the object. This maximum is determined by the Linkability Rules and prim scale limits. + Returns the rotation applied to the sun in the region. - llGetMemoryLimit + llGetRegionTimeDilation + arguments + energy - - sleep - 0.0 + 10 return - integer - arguments - + float + sleep + 0 tooltip - Get the maximum memory a script can use, in bytes. + Returns the current time dilation as a float between 0.0 (full dilation) and 1.0 (no dilation).\nReturns the current time dilation as a float between 0.0 and 1.0. - llGetMinScaleFactor + llGetRegionTimeOfDay + arguments + energy - 10.0 - sleep - 0.0 + 10 return float - arguments - + sleep + 0 tooltip - Returns a float that is the smallest scaling factor that can be used with llScaleByFactor to resize the object. This minimum is determined by the prim scale limits. + Returns the time in seconds since environmental midnight for the entire region. - llGetNextEmail + llGetRenderMaterial - energy - 10.0 - sleep - 0.0 - return - void arguments - Address + Face - type - string tooltip - - - - - Subject - + type - string - tooltip - + integer + energy + 10 + return + string + sleep + 0 tooltip - Fetch the next queued email with that matches the given address and/or subject, via the email event.\nIf the parameters are blank, they are not used for filtering. + Returns a string that is the render material on face (the inventory name if it is a material in the prim's inventory, otherwise the key).\nReturns the render material of a face, if it is found in object inventory, its key otherwise. - llGetNotecardLine + llGetRootPosition + arguments + energy - 10.0 - sleep - 0.1 + 10 return - key - arguments - - - NotecardName - - type - string - tooltip - - - - - LineNumber - - type - integer - tooltip - - - - + vector + sleep + 0 tooltip - Returns LineNumber from NotecardName via the dataserver event. The line index starts at zero.\nIf the requested line is passed the end of the note-card the dataserver event will return the constant EOF string.\nThe key returned by this function is a unique identifier which will be supplied to the dataserver event in the requested parameter. + Returns the position (in region coordinates) of the root prim of the object which the script is attached to.\nThis is used to allow a child prim to determine where the root is. - llGetNumberOfNotecardLines + llGetRootRotation + arguments + energy - 10.0 - sleep - 0.1 + 10 return - key - arguments - - - NotecardName - - type - string - tooltip - - - - + rotation + sleep + 0 tooltip - Returns the number of lines contained within a notecard via the dataserver event.\nThe key returned by this function is a query ID for identifying the dataserver reply. + Returns the rotation (relative to the region) of the root prim of the object which the script is attached to.\nGets the global rotation of the root object of the object script is attached to. - llGetNumberOfPrims + llGetRot + arguments + energy - 10.0 - sleep - 0.0 + 10 return - integer - arguments - + rotation + sleep + 0 tooltip - Returns the number of prims in a link set the script is attached to.\nReturns the number of prims in (and avatars seated on) the object the script is in. + Returns the rotation relative to the region's axes.\nReturns the rotation. - llGetNumberOfSides + llGetSPMaxMemory + arguments + energy - 10.0 - sleep - 0.0 + 10 return integer - arguments - + sleep + 0 tooltip - Returns the number of faces (or sides) of the prim.\nReturns the number of sides of the prim which has the script. + Returns the maximum used memory for the current script. Only valid after using PROFILE_SCRIPT_MEMORY. Non-mono scripts always use 16k.\nReturns the integer of the most bytes used while llScriptProfiler was last active. - llGetObjectDesc + llGetScale + arguments + energy - 10.0 - sleep - 0.0 + 10 return - string - arguments - + vector + sleep + 0 tooltip - Returns the description of the prim the script is attached to.\nReturns the description of the scripted object/prim. You can set the description using llSetObjectDesc. + Returns the scale of the prim.\nReturns a vector that is the scale (dimensions) of the prim. - llGetObjectDetails + llGetScriptName + arguments + energy - 10.0 - sleep - 0.0 + 10 return - list - arguments - - - ID - - type - key - tooltip - Prim or avatar UUID that is in the same region. - - - - Parameters - - type - list - tooltip - List of OBJECT_* flags. - - - + string + sleep + 0 tooltip - Returns a list of object details specified in the Parameters list for the object or avatar in the region with key ID.\nParameters are specified by the OBJECT_* constants. + Returns the name of the script that this function is used in.\nReturns the name of this script. - llGetObjectMass + llGetScriptState - energy - 10.0 - sleep - 0.0 - return - float arguments - ID + ScriptName - type - key tooltip - + + type + string - tooltip - Returns the mass of the avatar or object in the region.\nGets the mass of the object or avatar corresponding to ID. - - llGetObjectName - energy - 10.0 - sleep - 0.0 + 10 return - string - arguments - + integer + sleep + 0 tooltip - Returns the name of the prim which the script is attached to.\nReturns the name of the prim (not object) which contains the script. + Returns TRUE if the script named is running.\nReturns TRUE if ScriptName is running. - llGetObjectPermMask + llGetSimStats - energy - 10.0 - sleep - 0.0 - return - integer arguments - Category + StatType + tooltip + Statistic type. type integer - tooltip - Category is one of MASK_BASE, MASK_OWNER, MASK_GROUP, MASK_EVERYONE, or MASK_NEXT - tooltip - Returns the permission mask of the requested category for the object. - - llGetObjectPrimCount - energy - 10.0 - sleep - 0.0 + 10 return - integer - arguments - - - ObjectID - - type - key - tooltip - - - - + float + sleep + 0 tooltip - Returns the total number of prims for an object in the region.\nReturns the prim count for any object id in the same region. + Returns a float that is the requested statistic. - llGetOmega + llGetSimulatorHostname + arguments + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - + string + sleep + 10 tooltip - Returns the rotation velocity in radians per second.\nReturns a vector that is the rotation velocity of the object in radians per second. + Returns the host-name of the machine which the script is running on.\nFor example, "sim225.agni.lindenlab.com". - llGetOwner + llGetStartParameter + arguments + energy - 10.0 - sleep - 0.0 + 10 return - key - arguments - + integer + sleep + 0 tooltip - Returns the object owner's UUID.\nReturns the key for the owner of the object. + Returns an integer that is the script rez parameter.\nIf the object was rezzed by an agent, this function returns 0. - llGetOwnerKey + llGetStartString + arguments + energy - 10.0 - sleep - 0.0 + 10 return - key + string + sleep + 0 + tooltip + Returns an string that is the value passed to llRezObjectWithParams with REZ_PARAM_STRING.\nIf the object was rezzed by an agent, this function returns an empty string. + + llGetStaticPath + arguments - ObjectID + Start - type - key tooltip - + Starting position. + type + vector - - tooltip - Returns the owner of ObjectID.\nReturns the key for the owner of object ObjectID. - - llGetParcelDetails - - energy - 10.0 - sleep - 0.0 - return - list - arguments - - Position + End + tooltip + Ending position. type vector + + + + Radius + tooltip - Location within the region. + Radius of the character that the path is for, between 0.125m and 5.0m. + type + float - ParcelDetails + Parameters + tooltip + Currently only accepts the parameter CHARACTER_TYPE; the options are identical to those used for llCreateCharacter. The default value is CHARACTER_TYPE_NONE. type list - tooltip - List of details requested for the specified parcel location. + energy + 10 + return + list + sleep + 0 tooltip - Returns a list of parcel details specified in the ParcelDetails list for the parcel at Position.\nParameters is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA, _ID, _SEE_AVATARS.\nReturns a list that is the parcel details specified in ParcelDetails (in the same order) for the parcel at Position. + - llGetParcelFlags + llGetStatus - energy - 10.0 - sleep - 0.0 - return - integer arguments - Position + StatusFlag - type - vector tooltip - + A STATUS_* flag + type + integer - tooltip - Returns a mask of the parcel flags (PARCEL_FLAG_*) for the parcel that includes the point Position.\nReturns a bit-field specifying the parcel flags (PARCEL_FLAG_*) for the parcel at Position. - - llGetParcelMaxPrims - energy - 10.0 - sleep - 0.0 + 10 return integer + sleep + 0 + tooltip + Returns boolean value of the specified status (e.g. STATUS_PHANTOM) of the object the script is attached to. + + llGetSubString + arguments - Position + String - type - vector tooltip - Region coordinates (z is ignored) of parcel. + + type + string - SimWide + Start + tooltip + type integer + + + + End + tooltip - Boolean. If FALSE then the return is the maximum prims supported by the parcel. If TRUE then it is the combined number of prims on all parcels in the region owned by the specified parcel's owner. + + type + integer + energy + 10 + return + string + sleep + 0 tooltip - Returns the maximum number of prims allowed on the parcel at Position for a given scope.\nThe scope may be set to an individual parcel or the combined resources of all parcels with the same ownership in the region. + Returns a sub-string from String, in a range specified by the Start and End indicies (inclusive).\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would capture the entire string.\nIf Start is greater than End, the sub string is the exclusion of the entries. - llGetParcelMusicURL + llGetSunDirection + arguments + energy - - sleep - + 10 return - string - arguments - + vector + sleep + 0 tooltip - Gets the streaming audio URL for the parcel object is on.\nThe object owner, avatar or group, must also be the land owner. + Returns a normalized vector of the direction of the sun in the parcel.\nReturns the sun's direction on the simulator in the parcel. - llGetParcelPrimCount + llGetSunRotation + arguments + energy - 10.0 - sleep - 0.0 + 10 return - integer + rotation + sleep + 0 + tooltip + Returns the rotation applied to the sun in the parcel. + + llGetTexture + arguments - Position + Face - type - vector tooltip - Region coordinates of parcel to query. + + type + integer + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string that is the texture on face (the inventory name if it is a texture in the prim's inventory, otherwise the key).\nReturns the texture of a face, if it is found in object inventory, its key otherwise. + + llGetTextureOffset + + arguments + - Category + Face + tooltip + type integer - tooltip - A PARCEL_COUNT_* flag. + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the texture offset of face in the x and y components of a vector. + + llGetTextureRot + + arguments + - SimWide + Face + tooltip + type integer - tooltip - Boolean. If FALSE then the return is the maximum prims supported by the parcel. If TRUE then it is the combined number of prims on all parcels in the region owned by the specified parcel's owner. + energy + 10 + return + float + sleep + 0 tooltip - Returns the number of prims on the parcel at Position of the given category.\nCategories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP.\nReturns the number of prims used on the parcel at Position which are in Category.\nIf SimWide is TRUE, it returns the total number of objects for all parcels with matching ownership in the category specified.\nIf SimWide is FALSE, it returns the number of objects on this specific parcel in the category specified + Returns the texture rotation of side. - llGetParcelPrimOwners + llGetTextureScale - energy - 10.0 - sleep - 2.0 - return - list arguments - Position + Face - type - vector tooltip - + + type + integer + energy + 10 + return + vector + sleep + 0 tooltip - Returns a list of up to 100 residents who own objects on the parcel at Position, with per-owner land impact totals.\nRequires owner-like permissions for the parcel, and for the script owner to be present in the region.\nThe list is formatted as [ key agentKey1, integer agentLI1, key agentKey2, integer agentLI2, ... ], sorted by agent key.\nThe integers are the combined land impacts of the objects owned by the corresponding agents. + Returns the texture scale of side in the x and y components of a vector.\nReturns the texture scale of a side in the x and y components of a vector. - llGetPermissions + llGetTime + arguments + energy - 10.0 + 10 + return + float sleep - 0.0 + 0 + tooltip + Returns the time in seconds since the last region reset, script reset, or call to either llResetTime or llGetAndResetTime. + + llGetTimeOfDay + + arguments + + energy + 10 return - integer + float + sleep + 0 + tooltip + Returns the time in seconds since environmental midnight on the parcel. + + llGetTimestamp + arguments - + + energy + 10 + return + string + sleep + 0 tooltip - Returns an integer bitmask of the permissions that have been granted to the script. Individual permissions can be determined using a bit-wise "and" operation against the PERMISSION_* constants + Returns a time-stamp (UTC time zone) in the format: YYYY-MM-DDThh:mm:ss.ff..fZ. - llGetPermissionsKey + llGetTorque + arguments + energy - 10.0 + 10 + return + vector sleep - 0.0 + 0 + tooltip + Returns the torque (if the script is physical).\nReturns a vector that is the torque (if the script is physical). + + llGetUnixTime + + arguments + + energy + 10 return - key + integer + sleep + 0 + tooltip + Returns the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock. + + llGetUsedMemory + arguments - + + energy + 10 + return + integer + sleep + 0 tooltip - Returns the key of the avatar that last granted or declined permissions to the script.\nReturns NULL_KEY if permissions were never granted or declined. + Returns the current used memory for the current script. Non-mono scripts always use 16K.\nReturns the integer of the number of bytes of memory currently in use by the script. Non-mono scripts always use 16K. - llGetPhysicsMaterial + llGetUsername + arguments + + + AvatarID + + tooltip + + type + key + + + energy - - sleep - + 10 return - list - arguments - + string + sleep + 0 tooltip - Returns a list of the form [float gravity_multiplier, float restitution, float friction, float density]. + Returns the username of an avatar, if the avatar is connected to the current region, or if the name has been cached. Otherwise, returns an empty string. Use llRequestUsername if the avatar may be absent from the region. - llGetPos + llGetVel + arguments + energy - 10.0 - sleep - 0.0 + 10 return vector - arguments - + sleep + 0 tooltip - Returns the position of the task in region coordinates.\nReturns the vector position of the task in region coordinates. + Returns the velocity of the object.\nReturns a vector that is the velocity of the object. - llGetPrimitiveParams + llGetVisualParams - energy - 10.0 - sleep - 0.2 - return - list arguments + + ID + + tooltip + Avatar UUID in the same region. + type + key + + Parameters + tooltip + List of visual parameter IDs. type list - tooltip - PRIM_* flags and face parameters + energy + 10 + return + list + sleep + 0 tooltip - Returns the primitive parameters specified in the parameters list.\nReturns primitive parameters specified in the Parameters list. + Returns a list of the current value for each requested visual parameter. - llGetPrimMediaParams + llGetWallclock + arguments + energy - 10.0 - sleep - 0.1 + 10 return - list + float + sleep + 0 + tooltip + Returns the time in seconds since midnight California Pacific time (PST/PDT).\nReturns the time in seconds since simulator's time-zone midnight (Pacific Time). + + llGiveAgentInventory + arguments - Face + AgentID + tooltip + An agent in the region. type - integer + key + + + + FolderName + tooltip - face number + Folder name to give to the agent. + type + string - Parameters + InventoryItems + tooltip + Inventory items to give to the agent. type list + + + + Options + tooltip - One or more PRIM_MEDIA_* flags + A list of option for inventory transfer. + type + list - tooltip - Returns the media parameters for a particular face on an object, given the desired list of parameter names, in the order requested. Returns an empty list if no media exists on the face. - - llGetRegionAgentCount - energy - 10.0 - sleep - 0.0 + 10 return integer - arguments - - tooltip - Returns the number of avatars in the region.\nReturns an integer that is the number of avatars in the region. - - llGetRegionCorner - - energy - 10.0 sleep - 0.0 - return - vector - arguments - + 3 tooltip - Returns a vector, in meters, that is the global location of the south-west corner of the region which the object is in.\nReturns the Region-Corner of the simulator containing the task. The region-corner is a vector (values in meters) representing distance from the first region. + Give InventoryItems to the specified agent as a new folder of items, as permitted by the permissions system. The target must be an agent. - llGetRegionFlags + llGiveInventory - energy - 10.0 - sleep - 0.0 - return - integer arguments - - tooltip - Returns the region flags (REGION_FLAG_*) for the region the object is in.\nReturns a bit-field specifying the region flags (REGION_FLAG_*) for the region the object is in. - - llGetRegionFPS - + + + TargetID + + tooltip + + type + key + + + + InventoryItem + + tooltip + + type + string + + + energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - - tooltip - Returns the mean region frames per second. - - llGetRegionName - - energy - 10.0 + void sleep - 0.0 - return - string - arguments - + 0 tooltip - Returns the current region name. + Give InventoryItem to destination represented by TargetID, as permitted by the permissions system.\nTargetID may be any agent or an object in the same region. - llGetRegionTimeDilation + llGiveInventoryList - energy - 10.0 - sleep - 0.0 - return - float arguments - - tooltip - Returns the current time dilation as a float between 0.0 (full dilation) and 1.0 (no dilation).\nReturns the current time dilation as a float between 0.0 and 1.0. - - llGetRootPosition - + + + TargetID + + tooltip + + type + key + + + + FolderName + + tooltip + + type + string + + + + InventoryItems + + tooltip + + type + list + + + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - - tooltip - Returns the position (in region coordinates) of the root prim of the object which the script is attached to.\nThis is used to allow a child prim to determine where the root is. - - llGetRootRotation - - energy - 10.0 + void sleep - 0.0 - return - rotation - arguments - + 3 tooltip - Returns the rotation (relative to the region) of the root prim of the object which the script is attached to.\nGets the global rotation of the root object of the object script is attached to. + Give InventoryItems to destination (represented by TargetID) as a new folder of items, as permitted by the permissions system.\nTargetID may be any agent or an object in the same region. If TargetID is an object, the items are passed directly to the object inventory (no folder is created). - llGetRot + llGiveMoney - energy - 10.0 - sleep - 0.0 - return - rotation arguments - - tooltip - Returns the rotation relative to the region's axes.\nReturns the rotation. - - llGetScale - + + + AvatarID + + tooltip + + type + key + + + + Amount + + tooltip + + type + integer + + + energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - + integer + sleep + 0 tooltip - Returns the scale of the prim.\nReturns a vector that is the scale (dimensions) of the prim. + Transfers Amount of L$ from script owner to AvatarID.\nThis call will silently fail if PERMISSION_DEBIT has not been granted. - llGetScriptName + llGodLikeRezObject + arguments + + + InventoryItemID + + tooltip + + type + key + + + + Position + + tooltip + + type + vector + + + energy - 10.0 - sleep - 0.0 + 10 + god-mode + 1 return - string - arguments - + void + sleep + 0 tooltip - Returns the name of the script that this function is used in.\nReturns the name of this script. + Rez directly off of a UUID if owner has god-bit set. - llGetScriptState + llGround - energy - 10.0 - sleep - 0.0 - return - integer arguments - ScriptName + Offset - type - string tooltip - + + type + vector - tooltip - Returns TRUE if the script named is running.\nReturns TRUE if ScriptName is running. - - llGetSimStats - energy - 0 - sleep - 0 + 10 return float + sleep + 0 + tooltip + Returns the ground height at the object position + offset.\nReturns the ground height at the object's position + Offset. + + llGroundContour + arguments - StatType + Offset - type - integer tooltip - Statistic type. Currently only SIM_STAT_PCT_CHARS_STEPPED is supported. + + type + vector - tooltip - Returns a float that is the requested statistic. - - llGetSimulatorHostname - energy - 10.0 - sleep - 10.0 + 10 return - string - arguments - - tooltip - Returns the host-name of the machine which the script is running on.\nFor example, "sim225.agni.lindenlab.com". - - llGetSPMaxMemory - - energy - + vector sleep - 0.0 - return - integer - arguments - + 0 tooltip - Returns the maximum used memory for the current script. Only valid after using PROFILE_SCRIPT_MEMORY. Non-mono scripts always use 16k.\nReturns the integer of the most bytes used while llScriptProfiler was last active. + Returns the ground contour direction below the object position + Offset.\nReturns the ground contour at the object's position + Offset. - llGetStartParameter + llGroundNormal + arguments + + + Offset + + tooltip + + type + vector + + + energy - 10.0 - sleep - 0.0 + 10 return - integer - arguments - + vector + sleep + 0 tooltip - Returns an integer that is the script rez parameter.\nIf the object was rezzed by an agent, this function returns 0. + Returns the ground normal below the object position + offset.\nReturns the ground contour at the object's position + Offset. - llGetStaticPath + llGroundRepel - energy - 10.0 - sleep - 0.0 - return - list arguments - Start + Height - type - vector tooltip - Starting position. + Distance above the ground. + type + float - End + Water - type - vector tooltip - Ending position. + Boolean, if TRUE then hover above water too. + type + integer - Radius + Tau + tooltip + Seconds to critically damp in. type float - tooltip - Radius of the character that the path is for, between 0.125m and 5.0m. + + energy + 10 + return + void + sleep + 0 + tooltip + + Critically damps to height if within height * 0.5 of level (either above ground level or above the higher of land and water if water == TRUE).\nCritically damps to fHeight if within fHeight * 0.5 of ground or water level.\n + The height is above ground level if iWater is FALSE or above the higher of land and water if iWater is TRUE.\n + Do not use with vehicles. Only works in physics-enabled objects. + + + llGroundSlope + + arguments + - Parameters + Offset - type - list tooltip - Currently only accepts the parameter CHARACTER_TYPE; the options are identical to those used for llCreateCharacter. The default value is CHARACTER_TYPE_NONE. + + type + vector + energy + 10 + return + vector + sleep + 0 tooltip - + Returns the ground slope below the object position + Offset.\nReturns the ground slope at the object position + Offset. - llGetStatus + llHMAC - energy - 10.0 - sleep - 0.0 - return - integer arguments - StatusFlag + Key + tooltip + The PEM-formatted key for the hash digest. type - integer + string + + + + Message + tooltip - A STATUS_* flag + The message to be hashed. + type + string + + + + Algorithm + + tooltip + The digest algorithm: md5, sha1, sha224, sha256, sha384, sha512. + type + string - tooltip - Returns boolean value of the specified status (e.g. STATUS_PHANTOM) of the object the script is attached to. - - llGetSubString - energy - 10.0 - sleep - 0.0 + 10 return string + sleep + 0 + tooltip + Returns the base64-encoded hashed message authentication code (HMAC), of Message using PEM-formatted Key and digest Algorithm (md5, sha1, sha224, sha256, sha384, sha512). + + llHTTPRequest + arguments - String + URL + tooltip + A valid HTTP/HTTPS URL. type string + + + + Parameters + tooltip - + Configuration parameters, specified as HTTP_* flag-value pairs. + type + list - Start + Body + tooltip + Contents of the request. type - integer + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + Sends an HTTP request to the specified URL with the Body of the request and Parameters.\nReturns a key that is a handle identifying the HTTP request made. + + llHTTPResponse + + arguments + + + HTTPRequestID + tooltip - + A valid HTTP request key. + type + key - End + Status + tooltip + HTTP Status (200, 400, 404, etc.). type integer + + + + Body + tooltip - + Contents of the response. + type + string - tooltip - Returns a sub-string from String, in a range specified by the Start and End indicies (inclusive).\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would capture the entire string.\nIf Start is greater than End, the sub string is the exclusion of the entries. - - llGetSunDirection - energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - + void + sleep + 0 tooltip - Returns a normalized vector of the direction of the sun in the region.\nReturns the sun's direction on the simulator. + Responds to an incoming HTTP request which was triggerd by an http_request event within the script. HTTPRequestID specifies the request to respond to (this ID is supplied in the http_request event handler). Status and Body specify the status code and message to respond with. - llGetTexture + llHash + arguments + + + value + + tooltip + + type + string + + + energy - 10.0 - sleep - 0.0 + 10 return - string + integer + sleep + 0 + tooltip + Calculates the 32bit hash value for the provided string. + + llInsertString + arguments - Face + TargetVariable + + tooltip + + type + string + + + + Position + tooltip + type integer + + + + SourceVariable + tooltip - + + type + string + energy + 10 + return + string + sleep + 0 tooltip - Returns a string that is the texture on face (the inventory name if it is a texture in the prim's inventory, otherwise the key).\nReturns the texture of a face, if it is found in object inventory, its key otherwise. + Inserts SourceVariable into TargetVariable at Position, and returns the result.\nInserts SourceVariable into TargetVariable at Position and returns the result. Note this does not alter TargetVariable. - llGetTextureOffset + llInstantMessage - energy - 10.0 - sleep - 0.0 - return - vector arguments - Face + AvatarID + tooltip + type - integer + key + + + + Text + tooltip - + + type + string + energy + 10 + return + void + sleep + 2 tooltip - Returns the texture offset of face in the x and y components of a vector. + IMs Text to the user identified.\nSend Text to the user as an instant message. - llGetTextureRot + llIntegerToBase64 - energy - 10.0 - sleep - 0.0 - return - float arguments - Face + Value + tooltip + type integer - tooltip - + energy + 10 + return + string + sleep + 0 tooltip - Returns the texture rotation of side. + Returns a string that is a Base64 big endian encode of Value.\nEncodes the Value as an 8-character Base64 string. - llGetTextureScale + llIsFriend - energy - 10.0 - sleep - 0.0 - return - vector arguments - Face + agent_id - type - integer tooltip - + Agent ID of another agent in the region. + type + key - tooltip - Returns the texture scale of side in the x and y components of a vector.\nReturns the texture scale of a side in the x and y components of a vector. - - llGetTime - - energy - 10.0 - sleep - 0.0 - return - float - arguments - - tooltip - Returns the time in seconds since the last region reset, script reset, or call to either llResetTime or llGetAndResetTime. - - llGetTimeOfDay - energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - - tooltip - Returns the time in seconds since Second Life midnight or since region up-time, whichever is smaller.\nThe Second Life day cycle is 4 hours. - - llGetTimestamp - - energy - 10.0 + integer sleep - 0.0 - return - string - arguments - + 0 tooltip - Returns a time-stamp (UTC time zone) in the format: YYYY-MM-DDThh:mm:ss.ff..fZ. + Returns TRUE if avatar ID is a friend of the script owner. - llGetTorque + llJson2List - energy - 10.0 - sleep - 0.0 - return - vector arguments - - tooltip - Returns the torque (if the script is physical).\nReturns a vector that is the torque (if the script is physical). - - llGetUnixTime - + + + JSON + + tooltip + + type + string + + + energy - 10.0 - sleep - 0.0 + 10 return - integer - arguments - - tooltip - Returns the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock. - - llGetUsedMemory - - energy - 10.0 + list sleep - 0.0 - return - integer - arguments - + 0 tooltip - Returns the current used memory for the current script. Non-mono scripts always use 16K.\nReturns the integer of the number of bytes of memory currently in use by the script. Non-mono scripts always use 16K. + Converts the top level of the JSON string to a list. - llGetUsername + llJsonGetValue - energy - 10.0 - sleep - 0.0 - return - string arguments - AvatarID + JSON + tooltip + type - key + string + + + + Specifiers + tooltip - + + type + list - tooltip - Returns the username of an avatar, if the avatar is connected to the current region, or if the name has been cached. Otherwise, returns an empty string. Use llRequestUsername if the avatar may be absent from the region. - - llGetVel - energy - 10.0 - sleep - 0.0 + 10 return - vector - arguments - - tooltip - Returns the velocity of the object.\nReturns a vector that is the velocity of the object. - - llGetWallclock - - energy - 10.0 + string sleep - 0.0 - return - float - arguments - + 0 tooltip - Returns the time in seconds since midnight California Pacific time (PST/PDT).\nReturns the time in seconds since simulator's time-zone midnight (Pacific Time). + Gets the value indicated by Specifiers from the JSON string. - llGiveInventory + llJsonSetValue - energy - 10.0 - sleep - 0.0 - return - void arguments - TargetID + JSON + tooltip + type - key + string + + + + Specifiers + tooltip - + + type + list - InventoryItem + Value + tooltip + type string - tooltip - + energy + 10 + return + string + sleep + 0 tooltip - Give InventoryItem to destination represented by TargetID, as permitted by the permissions system.\nTargetID may be any agent or an object in the same region. + Returns a new JSON string that is the JSON given with the Value indicated by Specifiers set to Value. - llGiveInventoryList + llJsonValueType - energy - 10.0 - sleep - 3.0 - return - void arguments - TargetID + JSON - type - key tooltip - - - - - FolderName - + type string - tooltip - - InventoryItems + Specifiers + tooltip + type list - tooltip - + energy + 10 + return + string + sleep + 0 tooltip - Give InventoryItems to destination (represented by TargetID) as a new folder of items, as permitted by the permissions system.\nTargetID may be any agent or an object in the same region. If TargetID is an object, the items are passed directly to the object inventory (no folder is created). + Returns the type constant (JSON_*) for the value in JSON indicated by Specifiers. - llGiveMoney + llKey2Name - energy - 10.0 - sleep - 0.0 - return - integer arguments - AvatarID + ID - type - key tooltip - - - - - Amount - + Avatar or rezzed prim UUID. type - integer - tooltip - + key + energy + 10 + return + string + sleep + 0 tooltip - Transfers Amount of L$ from script owner to AvatarID.\nThis call will silently fail if PERMISSION_DEBIT has not been granted. + Returns the name of the prim or avatar specified by ID. The ID must be a valid rezzed prim or avatar key in the current simulator, otherwise an empty string is returned.\nFor avatars, the returned name is the legacy name - llGodLikeRezObject + llKeyCountKeyValue - god-mode - true + arguments + energy - 10.0 - sleep - 0.0 + 10 return - void + key + sleep + 0 + tooltip + + Starts an asychronous transaction the request the number of keys in the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will the the number of keys in the system. + + + llKeysKeyValue + arguments - InventoryItemID + First - type - key tooltip - + Index of the first key to return. + type + integer - Position + Count - type - vector tooltip - + The number of keys to return. + type + integer + energy + 10 + return + key + sleep + 0 tooltip - Rez directly off of a UUID if owner has god-bit set. + + Starts an asychronous transaction the request a number of keys from the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. The error XP_ERROR_KEY_NOT_FOUND is returned if First is greater than or equal to the number of keys in the data store. In the success case the subsequent items will be the keys requested. The number of keys returned may be less than requested if the return value is too large or if there is not enough keys remaining. The order keys are returned is not guaranteed but is stable between subsequent calls as long as no keys are added or removed. Because the keys are returned in a comma-delimited list it is not recommended to use commas in key names if this function is used. + - llGround + llLinear2sRGB - energy - 10.0 - sleep - 0.0 - return - float arguments - Offset + color + tooltip + A color in the linear colorspace. type vector - tooltip - - tooltip - Returns the ground height at the object position + offset.\nReturns the ground height at the object's position + Offset. - - llGroundContour - energy - 10.0 - sleep - 0.0 + 10 return vector + sleep + 0 + tooltip + Converts a color from the linear colorspace to sRGB. + + llLinkAdjustSoundVolume + arguments - Offset + LinkNumber + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag type - vector + integer + + + + Volume + tooltip - + The volume to set. + type + float + energy + 10 + return + void + sleep + 0 tooltip - Returns the ground contour direction below the object position + Offset.\nReturns the ground contour at the object's position + Offset. + Adjusts the volume (0.0 - 1.0) of the currently playing sound attached to the link.\nThis function has no effect on sounds started with llTriggerSound. - llGroundNormal + llLinkParticleSystem - energy - 10.0 - sleep - 0.0 - return - vector arguments - Offset + LinkNumber + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag type - vector + integer + + + + Rules + tooltip - + Particle system rules list in the format [ rule1, data1, rule2, data2 . . . ruleN, dataN ] + type + list - tooltip - Returns the ground normal below the object position + offset.\nReturns the ground contour at the object's position + Offset. - - llGroundRepel - energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + Creates a particle system in prim LinkNumber based on Rules. An empty list removes a particle system from object.\nList format is [ rule-1, data-1, rule-2, data-2 ... rule-n, data-n ].\nThis is identical to llParticleSystem except that it applies to a specified linked prim and not just the prim the script is in. + + llLinkPlaySound + arguments - Height + LinkNumber - type - float tooltip - Distance above the ground. + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer - Water + Sound - type - integer tooltip - Boolean, if TRUE then hover above water too. + + type + string - Tau + Volume + tooltip + type float + + + + Flags + tooltip - Seconds to critically damp in. + + type + integer + energy + 10 + return + void + sleep + 0 tooltip - Critically damps to height if within height * 0.5 of level (either above ground level or above the higher of land and water if water == TRUE).\nCritically damps to fHeight if within fHeight * 0.5 of ground or water level.\n - The height is above ground level if iWater is FALSE or above the higher of land and water if iWater is TRUE.\n - Do not use with vehicles. Only works in physics-enabled objects. + Plays Sound, once or looping, at Volume (0.0 - 1.0). The sound may be attached to the link or triggered at its location.\nOnly one sound may be attached to an object at a time, and attaching a new sound or calling llStopSound will stop the previously attached sound. - llGroundSlope + llLinkSetSoundQueueing - energy - 10.0 - sleep - 0.0 - return - vector arguments - Offset + LinkNumber + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag type - vector + integer + + + + QueueEnable + tooltip - + Boolean, sound queuing for the linked prim: TRUE enables, FALSE disables (default). + type + integer + energy + 10 + return + void + sleep + 0 tooltip - Returns the ground slope below the object position + Offset.\nReturns the ground slope at the object position + Offset. + Limits radius for audibility of scripted sounds (both attached and triggered) to distance Radius around the link. - llHTTPRequest + llLinkSetSoundRadius - energy - 10.0 - sleep - 0.0 - return - key arguments - URL + LinkNumber - type - string tooltip - A valid HTTP/HTTPS URL. - - - - Parameters - + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag type - list - tooltip - Configuration parameters, specified as HTTP_* flag-value pairs. + integer - Body + radius - type - string tooltip - Contents of the request. + Maximum distance that sounds can be heard. + type + float - tooltip - Sends an HTTP request to the specified URL with the Body of the request and Parameters.\nReturns a key that is a handle identifying the HTTP request made. - - llHTTPResponse - energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + Limits radius for audibility of scripted sounds (both attached and triggered) to distance Radius around the link. + + llLinkSitTarget + arguments - HTTPRequestID + LinkNumber - type - key tooltip - A valid HTTP request key. + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag of the prim. + type + integer - Status + Offset - type - integer tooltip - HTTP Status (200, 400, 404, etc.). + Position for the sit target, relative to the prim's position. + type + vector - Body + Rotation - type - string tooltip - Contents of the response. + Rotation (relative to the prim's rotation) for the avatar. + type + rotation + energy + 10 + return + void + sleep + 0 tooltip - Responds to an incoming HTTP request which was triggerd by an http_request event within the script. HTTPRequestID specifies the request to respond to (this ID is supplied in the http_request event handler). Status and Body specify the status code and message to respond with. + Set the sit location for the linked prim(s). If Offset == <0,0,0> clear it.\nSet the sit location for the linked prim(s). The sit location is relative to the prim's position and rotation. - llInsertString + llLinkStopSound - energy - 10.0 - sleep - 0.0 - return - string arguments - TargetVariable + LinkNumber - type - string tooltip - - - - - Position - + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag type integer - tooltip - - - - - SourceVariable - - type - string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Inserts SourceVariable into TargetVariable at Position, and returns the result.\nInserts SourceVariable into TargetVariable at Position and returns the result. Note this does not alter TargetVariable. + Stops playback of the currently attached sound on a link. - llInstantMessage + llLinksetDataAvailable + arguments + energy - 10.0 - sleep - 2.0 + 10 return - void + integer + sleep + 0 + tooltip + Returns the number of bytes remaining in the linkset's datastore. + + llLinksetDataCountFound + arguments - AvatarID + search - type - key tooltip - - - - - Text - + A regex search string to match against keys in the datastore. type string - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip - IMs Text to the user identified.\nSend Text to the user as an instant message. + Returns the number of keys matching the regular expression passed in the search parameter. - llIntegerToBase64 + llLinksetDataCountKeys + arguments + energy - 10.0 - sleep - 0.0 + 10 return - string + integer + sleep + 0 + tooltip + Returns the number of keys in the linkset's datastore. + + llLinksetDataDelete + arguments - Value + name - type - integer tooltip - + Key to delete from the linkset's datastore. + type + string + energy + 10 + return + integer + sleep + 0 tooltip - Returns a string that is a Base64 big endian encode of Value.\nEncodes the Value as an 8-character Base64 string. + Deletes a name:value pair from the linkset's datastore. - llJson2List + llLinksetDataDeleteFound - energy - 0.0 - sleep - 0.0 - return - list arguments - JSON + search + tooltip + A regex search string to match against keys in the datastore. type string + + + + pass + tooltip - + The pass phrase used to protect key value pairs in the linkset data + type + string + energy + 10 + return + list + sleep + 0 tooltip - Converts the top level of the JSON string to a list. + Deletes all key value pairs in the linkset data where the key matches the regular expression in search. Returns a list consisting of [ #deleted, #not deleted ]. - llJsonGetValue + llLinksetDataDeleteProtected - energy - 0.0 - sleep - 0.0 - return - string arguments - JSON + name + tooltip + Key to delete from the linkset's datastore. type string - tooltip - - Specifiers + pass - type - list tooltip - + Pass phrase to access protected data. + type + string + energy + 10 + return + integer + sleep + 0 tooltip - Gets the value indicated by Specifiers from the JSON string. + Deletes a name:value pair from the linkset's datastore. - llJsonSetValue + llLinksetDataFindKeys - energy - 0.0 - sleep - 0.0 - return - string arguments - JSON + search + tooltip + A regex search string to match against keys in the datastore. type string - tooltip - - Specifiers + start - type - list tooltip - + First entry to return. 0 for start of list. + type + integer - Value + count - type - string tooltip - + Number of entries to return. Less than 1 for all keys. + type + integer + energy + 10 + return + list + sleep + 0 tooltip - Returns a new JSON string that is the JSON given with the Value indicated by Specifiers set to Value. + Returns a list of keys from the linkset's data store matching the search parameter. - llJsonValueType + llLinksetDataListKeys - energy - 0.0 - sleep - 0.0 - return - string arguments - JSON + start - type - string tooltip - + First entry to return. 0 for start of list. + type + integer - Specifiers + count - type - list tooltip - + Number of entries to return. Less than 1 for all keys. + type + integer + energy + 10 + return + list + sleep + 0 tooltip - Returns the type constant (JSON_*) for the value in JSON indicated by Specifiers. + Returns a list of all keys in the linkset datastore. - llKey2Name + llLinksetDataRead - energy - 10.0 - sleep - 0.0 - return - string arguments - ID + name - type - key tooltip - Avatar or rezzed prim UUID. + Key to retrieve from the linkset's datastore. + type + string - tooltip - Returns the name of the prim or avatar specified by ID. The ID must be a valid rezzed prim or avatar key in the current simulator, otherwise an empty string is returned.\nFor avatars, the returned name is the legacy name - - llKeyCountKeyValue - energy - 10.0 - sleep - 0.0 + 10 return - key - arguments - + string + sleep + 0 tooltip - - Starts an asychronous transaction the request the number of keys in the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will the the number of keys in the system. - + Returns the value stored for a key in the linkset. - llKeysKeyValue + llLinksetDataReadProtected - energy - 10.0 - sleep - 0.0 - return - key arguments - - First - - type - integer - tooltip - Index of the first key to return. - - - - Count - - type - integer - tooltip - The number of keys to return. - - + + name + + tooltip + Key to retrieve from the linkset's datastore. + type + string + + + + pass + + tooltip + Pass phrase to access protected data. + type + string + + + energy + 10 + return + string + sleep + 0 tooltip - - Starts an asychronous transaction the request a number of keys from the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. The error XP_ERROR_KEY_NOT_FOUND is returned if First is greater than or equal to the number of keys in the data store. In the success case the subsequent items will be the keys requested. The number of keys returned may be less than requested if the return value is too large or if there is not enough keys remaining. The order keys are returned is not guaranteed but is stable between subsequent calls as long as no keys are added or removed. Because the keys are returned in a comma-delimited list it is not recommended to use commas in key names if this function is used. - + Returns the value stored for a key in the linkset. - llLinkParticleSystem + llLinksetDataReset + arguments + energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + Resets the linkset's data store, erasing all key-value pairs. + + llLinksetDataWrite + arguments - LinkNumber + name - type - integer tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + key for the name:value pair. + type + string - Rules + value - type - list tooltip - Particle system rules list in the format [ rule1, data1, rule2, data2 . . . ruleN, dataN ] + value to store in the linkset's datastore. + type + string + energy + 10 + return + integer + sleep + 0 tooltip - Creates a particle system in prim LinkNumber based on Rules. An empty list removes a particle system from object.\nList format is [ rule-1, data-1, rule-2, data-2 ... rule-n, data-n ].\nThis is identical to llParticleSystem except that it applies to a specified linked prim and not just the prim the script is in. + Sets a name:value pair in the linkset's datastore - llLinkSitTarget + llLinksetDataWriteProtected - energy - 10.0 - sleep - 0.0 - return - void arguments - LinkNumber + name - type - integer tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag of the prim. + key for the name:value pair. + type + string - Offset + value - type - vector tooltip - Position for the sit target, relative to the prim's position. + value to store in the linkset's datastore. + type + string - Rotation + pass - type - rotation tooltip - Rotation (relative to the prim's rotation) for the avatar. + Pass phrase to access protected data. + type + string + energy + 10 + return + integer + sleep + 0 tooltip - Set the sit location for the linked prim(s). If Offset == <0,0,0> clear it.\nSet the sit location for the linked prim(s). The sit location is relative to the prim's position and rotation. + Sets a name:value pair in the linkset's datastore llList2CSV - energy - 10.0 - sleep - 0.0 - return - string arguments ListVariable + tooltip + type list - tooltip - + energy + 10 + return + string + sleep + 0 tooltip Creates a string of comma separated values from the list.\nCreate a string of comma separated values from the specified list. llList2Float - energy - 10.0 - sleep - 0.0 - return - float arguments ListVariable + tooltip + type list - tooltip - Index + tooltip + type integer - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Copies the float at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to a float, then zero is returned. llList2Integer - energy - 10.0 - sleep - 0.0 - return - integer arguments ListVariable + tooltip + type list - tooltip - Index + tooltip + type integer - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip Copies the integer at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to an integer, then zero is returned. llList2Json - energy - 0 - sleep - 0 - return - string arguments JsonType - type - string tooltip Type is JSON_ARRAY or JSON_OBJECT. + type + string Values - type - list tooltip List of values to convert. + type + list + energy + 10 + return + string + sleep + 0 tooltip Converts either a strided list of key:value pairs to a JSON_OBJECT, or a list of values to a JSON_ARRAY. llList2Key - energy - 10.0 - sleep - 0.0 - return - key arguments ListVariable + tooltip + type list - tooltip - Index + tooltip + type integer - tooltip - + energy + 10 + return + key + sleep + 0 tooltip Copies the key at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to a key, then null string is returned. llList2List + arguments + + + ListVariable + + tooltip + + type + list + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + energy - 10.0 - sleep - 0.0 + 10 return list + sleep + 0 + tooltip + Returns a subset of entries from ListVariable, in a range specified by the Start and End indicies (inclusive).\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would capture the entire string.\nIf Start is greater than End, the sub string is the exclusion of the entries. + + llList2ListSlice + arguments ListVariable + tooltip + type list - tooltip - Start + tooltip + type integer - tooltip - End + tooltip + + type + integer + + + + Stride + + tooltip + type integer + + + + slice_index + tooltip - + + type + integer + energy + 10 + return + list + sleep + 0 tooltip - Returns a subset of entries from ListVariable, in a range specified by the Start and End indicies (inclusive).\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would capture the entire string.\nIf Start is greater than End, the sub string is the exclusion of the entries. + Returns a subset of entries from ListVariable, in a range specified by Start and End indices (inclusive) return the slice_index element of each stride.\n Using negative numbers for Start and/or End causes the index to count backwards from the length of the list. (e.g. 0, -1 captures entire list)\nIf slice_index is less than 0, it is counted backwards from the end of the stride.\n Stride must be a positive integer > 0 or an empy list is returned. If slice_index falls outside range of stride, an empty list is returned. slice_index is zero-based. (e.g. A stride of 2 has valid indices 0,1) llList2ListStrided - energy - 10.0 - sleep - 0.0 - return - list arguments ListVariable + tooltip + type list - tooltip - Start + tooltip + type integer - tooltip - End + tooltip + type integer - tooltip - Stride + tooltip + type integer - tooltip - + energy + 10 + return + list + sleep + 0 tooltip Copies the strided slice of the list from Start to End.\nReturns a copy of the strided slice of the specified list from Start to End. llList2Rot - energy - 10.0 - sleep - 0.0 - return - rotation arguments ListVariable + tooltip + type list - tooltip - Index + tooltip + type integer - tooltip - + energy + 10 + return + rotation + sleep + 0 tooltip Copies the rotation at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to rotation, thenZERO_ROTATION is returned. llList2String - energy - 10.0 - sleep - 0.0 - return - string arguments ListVariable + tooltip + type list - tooltip - Index + tooltip + type integer - tooltip - + energy + 10 + return + string + sleep + 0 tooltip Copies the string at Index in the list.\nReturns the value at Index in the specified list as a string. If Index describes a location not in the list then null string is returned. llList2Vector - energy - 10.0 - sleep - 0.0 - return - vector arguments ListVariable + tooltip + type list - tooltip - Index + tooltip + type integer - tooltip - + energy + 10 + return + vector + sleep + 0 tooltip Copies the vector at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to a vector, then ZERO_VECTOR is returned. - llListen + llListFindList - energy - 10.0 - sleep - 0.0 - return - integer arguments - Channel + ListVariable - type - integer tooltip - - - - - SpeakersName - + type - string - tooltip - + list - SpeakersID + Find - type - key tooltip - - - - - Text - + type - string - tooltip - + list + energy + 10 + return + integer + sleep + 0 tooltip - Creates a listen callback for Text on Channel from SpeakersName and SpeakersID (SpeakersName, SpeakersID, and/or Text can be empty) and returns an identifier that can be used to deactivate or remove the listen.\nNon-empty values for SpeakersName, SpeakersID, and Text will filter the results accordingly, while empty strings and NULL_KEY will not filter the results, for string and key parameters respectively.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. + Returns the index of the first instance of Find in ListVariable. Returns -1 if not found.\nReturns the position of the first instance of the Find list in the ListVariable. Returns -1 if not found. - llListenControl + llListFindListNext - energy - 10.0 - sleep - 0.0 - return - void arguments - ChannelHandle + ListVariable - type - integer tooltip - + + type + list - Active + Find - type - integer tooltip - + + type + list - - tooltip - Makes a listen event callback active or inactive. Pass in the value returned from llListen to the iChannelHandle parameter to specify which listener you are controlling.\nUse boolean values to specify Active - - llListenRemove - - energy - 10.0 - sleep - 0.0 - return - void - arguments - - ChannelHandle + Instance + tooltip + type integer - tooltip - - tooltip - Removes a listen event callback. Pass in the value returned from llListen to the iChannelHandle parameter to specify which listener to remove. - - llListFindList - energy - 10.0 - sleep - 0.0 + 10 return integer + sleep + 0 + tooltip + Returns the index of the nth instance of Find in ListVariable. Returns -1 if not found. + + llListFindStrided + arguments ListVariable + tooltip + + type + list + + + + Find + + tooltip + type list + + + + Start + tooltip - + + type + integer - Find + End + tooltip + type - list + integer + + + + Stride + tooltip - + + type + integer + energy + 10 + return + integer + sleep + 0 tooltip - Returns the index of the first instance of Find in ListVariable. Returns -1 if not found.\nReturns the position of the first instance of the Find list in the ListVariable. Returns -1 if not found. + Returns the index of the first instance of Find in ListVariable. Returns -1 if not found.\nReturns the position of the first instance of the Find list in the ListVariable after the start index and before the end index. Steps through ListVariable by stride. Returns -1 if not found. llListInsertList - energy - 10.0 - sleep - 0.0 - return - list arguments Target + tooltip + type list - tooltip - ListVariable + tooltip + type list - tooltip - Position + tooltip + type integer - tooltip - + energy + 10 + return + list + sleep + 0 tooltip Returns a list that contains all the elements from Target but with the elements from ListVariable inserted at Position start.\nReturns a new list, created by inserting ListVariable into the Target list at Position. Note this does not alter the Target. llListRandomize - energy - 10.0 - sleep - 0.0 - return - list arguments ListVariable + tooltip + type list - tooltip - Stride + tooltip + type integer - tooltip - + energy + 10 + return + list + sleep + 0 tooltip Returns a version of the input ListVariable which has been randomized by blocks of size Stride.\nIf the remainder from the length of the list, divided by the stride is non-zero, this function does not randomize the list. llListReplaceList - energy - 10.0 - sleep - 0.0 - return - list arguments Target + tooltip + type list - tooltip - ListVariable + tooltip + type list - tooltip - Start + tooltip + type integer - tooltip - End + tooltip + type integer - tooltip - + energy + 10 + return + list + sleep + 0 tooltip Returns a list that is Target with Start through End removed and ListVariable inserted at Start.\nReturns a list replacing the slice of the Target list from Start to End with the specified ListVariable. Start and End are inclusive, so 0, 1 would replace the first two entries and 0, 0 would replace only the first list entry. llListSort + arguments + + + ListVariable + + tooltip + List to sort. + type + list + + + + Stride + + tooltip + Stride length. + type + integer + + + + Ascending + + tooltip + Boolean. TRUE = result in ascending order, FALSE = result in descending order. + type + integer + + + energy - 10.0 - sleep - 0.0 + 10 return list + sleep + 0 + tooltip + Returns the specified list, sorted into blocks of stride in ascending order (if Ascending is TRUE, otherwise descending). Note that sort only works if the first entry of each block is the same datatype. + + llListSortStrided + arguments ListVariable - type - list tooltip List to sort. + type + list Stride - type - integer tooltip Stride length. + type + integer - Ascending + Sortkey + tooltip + The zero based element within the stride to use as the sort key type integer + + + + Ascending + tooltip Boolean. TRUE = result in ascending order, FALSE = result in descending order. + type + integer + energy + 10 + return + list + sleep + 0 tooltip - Returns the specified list, sorted into blocks of stride in ascending order (if Ascending is TRUE, otherwise descending). Note that sort only works if the first entry of each block is the same datatype. + Returns the specified list, sorted by the specified element into blocks of stride in ascending order (if Ascending is TRUE, otherwise descending). Note that sort only works if the first entry of each block is the same datatype. llListStatistics + arguments + + + Operation + + tooltip + One of LIST_STAT_* values + type + integer + + + + ListVariable + + tooltip + Variable to analyze. + type + list + + + energy - 10.0 - sleep - 0.0 + 10 return float + sleep + 0 + tooltip + Performs a statistical aggregate function, specified by a LIST_STAT_* constant, on ListVariables.\nThis function allows a script to perform a statistical operation as defined by operation on a list composed of integers and floats. + + llListen + arguments - Operation + Channel + tooltip + type integer + + + + SpeakersName + tooltip - One of LIST_STAT_* values + + type + string - ListVariable + SpeakersID + tooltip + type - list + key + + + + Text + tooltip - Variable to analyze. + + type + string + energy + 10 + return + integer + sleep + 0 tooltip - Performs a statistical aggregate function, specified by a LIST_STAT_* constant, on ListVariables.\nThis function allows a script to perform a statistical operation as defined by operation on a list composed of integers and floats. + Creates a listen callback for Text on Channel from SpeakersName and SpeakersID (SpeakersName, SpeakersID, and/or Text can be empty) and returns an identifier that can be used to deactivate or remove the listen.\nNon-empty values for SpeakersName, SpeakersID, and Text will filter the results accordingly, while empty strings and NULL_KEY will not filter the results, for string and key parameters respectively.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. - llLoadURL + llListenControl + arguments + + + ChannelHandle + + tooltip + + type + integer + + + + Active + + tooltip + + type + integer + + + energy - 10.0 + 10 + return + void sleep - 0.1 + 0 + tooltip + Makes a listen event callback active or inactive. Pass in the value returned from llListen to the iChannelHandle parameter to specify which listener you are controlling.\nUse boolean values to specify Active + + llListenRemove + + arguments + + + ChannelHandle + + tooltip + + type + integer + + + + energy + 10 return void + sleep + 0 + tooltip + Removes a listen event callback. Pass in the value returned from llListen to the iChannelHandle parameter to specify which listener to remove. + + llLoadURL + arguments AvatarID + tooltip + type key - tooltip - Text + tooltip + type string - tooltip - URL + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0.1000000000000000055511151 tooltip Shows dialog to avatar AvatarID offering to load web page at URL. If user clicks yes, launches their web browser.\nllLoadURL displays a dialogue box to the user, offering to load the specified web page using the default web browser. - llLog - - energy - 10.0 - sleep - 0.0 - return - float + llLog + arguments Value + tooltip + type float - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Returns the natural logarithm of Value. Returns zero if Value <= 0.\nReturns the base e (natural) logarithm of the specified Value. llLog10 - energy - 10.0 - sleep - 0.0 - return - float arguments Value + tooltip + type float - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Returns the base 10 logarithm of Value. Returns zero if Value <= 0.\nReturns the base 10 (common) logarithm of the specified Value. llLookAt - energy - 10.0 - sleep - 0.0 - return - void arguments Target + tooltip + type vector - tooltip - Strength + tooltip + type float - tooltip - Damping + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Cause object name to point its forward axis towards Target, at a force controlled by Strength and Damping.\nGood Strength values are around half the mass of the object and good Damping values are less than 1/10th of the Strength.\nAsymmetrical shapes require smaller Damping. A Strength of 0.0 cancels the look at. llLoopSound - energy - 10.0 - sleep - 0.0 - return - void arguments Sound + tooltip + type string - tooltip - Volume + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Plays specified Sound, looping indefinitely, at Volume (0.0 - 1.0).\nOnly one sound may be attached to an object at a time.\nA second call to llLoopSound with the same key will not restart the sound, but the new volume will be used. This allows control over the volume of already playing sounds.\nSetting the volume to 0 is not the same as calling llStopSound; a sound with 0 volume will continue to loop.\nTo restart the sound from the beginning, call llStopSound before calling llLoopSound again. llLoopSoundMaster - energy - 10.0 - sleep - 0.0 - return - void arguments Sound + tooltip + type string - tooltip - Volume + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Plays attached Sound, looping at volume (0.0 - 1.0), and declares it a sync master.\nBehaviour is identical to llLoopSound, with the addition of marking the source as a "Sync Master", causing "Slave" sounds to sync to it. If there are multiple masters within a viewers interest area, the most audible one (a function of both distance and volume) will win out as the master.\nThe use of multiple masters within a small area is unlikely to produce the desired effect. + Plays attached Sound, looping at volume (0.0 - 1.0), and declares it a sync master.\nBehaviour is identical to llLoopSound, with the addition of marking the source as a "Sync Master", causing "Slave" sounds to sync to it. If there are multiple masters within a viewers interest area, the most audible one (a function of both distance and volume) will win out as the master.\nThe use of multiple masters within a small area is unlikely to produce the desired effect. llLoopSoundSlave - energy - 10.0 - sleep - 0.0 - return - void arguments Sound + tooltip + type string - tooltip - Volume + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Plays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master.\nBehaviour is identical to llLoopSound, unless there is a "Sync Master" present.\nIf a Sync Master is already playing the Slave sound will begin playing from the same point the master is in its loop synchronizing the loop points of both sounds.\nIf a Sync Master is started when the Slave is already playing, the Slave will skip to the correct position to sync with the Master. + Plays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master.\nBehaviour is identical to llLoopSound, unless there is a "Sync Master" present.\nIf a Sync Master is already playing the Slave sound will begin playing from the same point the master is in its loop synchronizing the loop points of both sounds.\nIf a Sync Master is started when the Slave is already playing, the Slave will skip to the correct position to sync with the Master. - llMakeExplosion + llMD5String - deprecated - true + arguments + + + Text + + tooltip + + type + string + + + + Nonce + + tooltip + + type + integer + + + energy - 10.0 - sleep - 0.1 + 10 return - void + string + sleep + 0 + tooltip + Returns a string of 32 hex characters that is an RSA Data Security Inc., MD5 Message-Digest Algorithm of Text with Nonce used as the salt.\nReturns a 32-character hex string. (128-bit in binary.) + + llMakeExplosion + arguments Particles + tooltip + type integer - tooltip - Scale + tooltip + type float - tooltip - Velocity + tooltip + type float - tooltip - Lifetime + tooltip + type float - tooltip - Arc + tooltip + type float - tooltip - Texture + tooltip + type string - tooltip - Offset + tooltip + type vector - tooltip - + deprecated + 1 + energy + 10 + return + void + sleep + 0.1000000000000000055511151 tooltip Make a round explosion of particles. Deprecated: Use llParticleSystem instead.\nMake a round explosion of particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead. llMakeFire - deprecated - true - energy - 10.0 - sleep - 0.1 - return - void arguments Particles + tooltip + type integer - tooltip - Scale + tooltip + type float - tooltip - Velocity + tooltip + type float - tooltip - Lifetime + tooltip + type float - tooltip - Arc + tooltip + type float - tooltip - Texture + tooltip + type string - tooltip - Offset + tooltip + type vector - tooltip - + deprecated + 1 + energy + 10 + return + void + sleep + 0.1000000000000000055511151 tooltip Make fire like particles. Deprecated: Use llParticleSystem instead.\nMake fire particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead. llMakeFountain - deprecated - true - energy - 10.0 - sleep - 0.1 - return - void arguments Particles + tooltip + type integer - tooltip - Scale + tooltip + type float - tooltip - Velocity + tooltip + type float - tooltip - Lifetime + tooltip + type float - tooltip - Arc + tooltip + type float - tooltip - Bounce + tooltip + type integer - tooltip - Texture + tooltip + type string - tooltip - Offset + tooltip + type vector - tooltip - Bounce_Offset + tooltip + type float - tooltip - + deprecated + 1 + energy + 10 + return + void + sleep + 0.1000000000000000055511151 tooltip Make a fountain of particles. Deprecated: Use llParticleSystem instead.\nMake a fountain of particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead. llMakeSmoke - deprecated - true - energy - 10.0 - sleep - 0.1 - return - void arguments Particles + tooltip + type integer - tooltip - Scale + tooltip + type float - tooltip - Velocity + tooltip + type float - tooltip - Lifetime + tooltip + type float - tooltip - Arc + tooltip + type float - tooltip - Texture + tooltip + type string - tooltip - Offset + tooltip + type vector - tooltip - + deprecated + 1 + energy + 10 + return + void + sleep + 0.1000000000000000055511151 tooltip Make smoke like particles. Deprecated: Use llParticleSystem instead.\nMake smoky particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead. llManageEstateAccess - energy - - sleep - - return - integer arguments Action - type - integer tooltip One of the ESTATE_ACCESS_ALLOWED_* actions. + type + integer AvatarID - type - key tooltip UUID of the avatar or group to act upon. + type + key + energy + 10 + return + integer + sleep + 0 tooltip - Adds or removes agents from the estate's agent access or ban lists, or groups to the estate's group access list. Action is one of the ESTATE_ACCESS_ALLOWED_* operations to perform.\nReturns an integer representing a boolean, TRUE if the call was successful; FALSE if throttled, invalid action, invalid or null id or object owner is not allowed to manage the estate.\nThe object owner is notified of any changes, unless PERMISSION_SILENT_ESTATE_MANAGEMENT has been granted to the script. + Adds or removes agents from the estate's agent access or ban lists, or groups to the estate's group access list. Action is one of the ESTATE_ACCESS_ALLOWED_* operations to perform.\nReturns an integer representing a boolean, TRUE if the call was successful; FALSE if throttled, invalid action, invalid or null id or object owner is not allowed to manage the estate.\nThe object owner is notified of any changes, unless PERMISSION_SILENT_ESTATE_MANAGEMENT has been granted to the script. - llMapDestination + llMapBeacon - energy - 10.0 - sleep - 1.0 - return - void arguments RegionName + tooltip + Region in which to show the beacon. type string - tooltip - Position + tooltip + Position within region to show the beacon. type vector - tooltip - - Direction + Options - type - vector tooltip - + Options + type + list + energy + 10 + return + void + sleep + 1 tooltip - Opens world map for avatar who touched is is wearing the script, centred on RegionName with Position highlighted. Only works for scripts attached to avatar, or during touch events.\nDirection currently has no effect. + Displays an in world beacon and optionally opens world map for avatar who touched the object or is wearing the script, centered on RegionName with Position highlighted. Only works for scripts attached to avatar, or during touch events. - llMD5String + llMapDestination - energy - 10.0 - sleep - 0.0 - return - string arguments - Text + RegionName + tooltip + type string + + + + Position + tooltip - + + type + vector - Nonce + Direction - type - integer tooltip - + + type + vector + energy + 10 + return + void + sleep + 1 tooltip - Returns a string of 32 hex characters that is an RSA Data Security Inc., MD5 Message-Digest Algorithm of Text with Nonce used as the salt.\nReturns a 32-character hex string. (128-bit in binary.) + Opens world map for avatar who touched is is wearing the script, centred on RegionName with Position highlighted. Only works for scripts attached to avatar, or during touch events.\nDirection currently has no effect. llMessageLinked - energy - 10.0 - sleep - 0.0 - return - void arguments LinkNumber + tooltip + type integer - tooltip - Number + tooltip + type integer - tooltip - Text + tooltip + type string - tooltip - ID + tooltip + type key - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sends Number, Text, and ID to members of the link set identified by LinkNumber.\nLinkNumber is either a linked number (available through llGetLinkNumber) or a LINK_* constant. llMinEventDelay - energy - 10.0 - sleep - 0.0 - return - void arguments Delay + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Set the minimum time between events being handled. - llModifyLand + llModPow - energy - 10.0 - sleep - 0.0 - return - void arguments - Action + Value + tooltip + type integer - tooltip - LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE or LAND_REVERT - Area + Power + tooltip + type integer + + + + Modulus + tooltip - 0, 1, 2 (2m x 2m, 4m x 4m, or 8m x 8m) + + type + integer - tooltip - Modify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT) on size (0, 1, 2, corresponding to 2m x 2m, 4m x 4m, 8m x 8m). - - llModPow - energy - 10.0 - sleep - 1.0 + 10 return integer + sleep + 0 + tooltip + Returns a Value raised to the Power, mod Modulus. ((a**b)%c) b is capped at 0xFFFF (16 bits).\nReturns (Value ^ Power) % Modulus. (Value raised to the Power, Modulus). Value is capped at 0xFFFF (16 bits). + + llModifyLand + arguments - Value + Action - type - integer tooltip - - - - - Power - + LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE or LAND_REVERT type integer - tooltip - - Modulus + Area + tooltip + 0, 1, 2 (2m x 2m, 4m x 4m, or 8m x 8m) type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Returns a Value raised to the Power, mod Modulus. ((a**b)%c) b is capped at 0xFFFF (16 bits).\nReturns (Value ^ Power) % Modulus. (Value raised to the Power, Modulus). Value is capped at 0xFFFF (16 bits). + Modify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT) on size (0, 1, 2, corresponding to 2m x 2m, 4m x 4m, 8m x 8m). llMoveToTarget - energy - 10.0 - sleep - 0.0 - return - void arguments Target + tooltip + type vector - tooltip - Tau + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Critically damp to Target in Tau seconds (if the script is physical).\nCritically damp to position target in tau-seconds if the script is physical. Good tau-values are greater than 0.2. A tau of 0.0 stops the critical damping. - llNavigateTo + llName2Key + arguments + + + Name + + tooltip + Name of agent in region to look up. + type + string + + + energy - - sleep - + 10 return - void + key + sleep + 0 + tooltip + Look up Agent ID for the named agent in the region. + + llNavigateTo + arguments Location - type - vector tooltip Region coordinates for the character to navigate to. + type + vector Options - type - list tooltip List of parameters to control the type of path-finding used. Currently only FORCE_DIRECT_PATH supported. + type + list + energy + 10 + return + void + sleep + 0 tooltip Navigate to destination.\nDirects an object to travel to a defined position in the region or adjacent regions. llOffsetTexture - energy - 10.0 - sleep - 0.2 - return - void arguments OffsetS + tooltip + type float - tooltip - OffsetT + tooltip + type float - tooltip - Face + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0.2000000000000000111022302 tooltip Sets the texture S and T offsets for the chosen Face.\nIf Face is ALL_SIDES this function sets the texture offsets for all faces. + llOpenFloater + + arguments + + + floater_name + + tooltip + Identifier for floater to open + type + string + + + + url + + tooltip + URL to pass to floater + type + string + + + + params + + tooltip + Parameters to apply to open floater + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the value for header for request_id.\nReturns a string that is the value of the Header for HTTPRequestID. + llOpenRemoteDataChannel + arguments + deprecated - true + 1 energy - 10.0 - sleep - 1.0 + 10 return void - arguments - + sleep + 1 tooltip - Requests a channel to listen for XML-RPC calls. (Deprecated: XML-RPC should not be used. Use http-in instead.)\nWill trigger a remote_data event with type = REMOTE_DATA_CHANNEL and a channel ID (key) once it is available.\nThis channel ID must be referenced in the XML-RPC call to the script (from the internet) -- so the key must somehow get to the external XML-RPC client. + This function is deprecated. - llOverMyLand + llOrd + arguments + + + value + + tooltip + The string to convert to Unicode. + type + string + + + + index + + tooltip + Index of character to convert to unicode. + type + integer + + + energy - 10.0 - sleep - 0.0 + 10 return integer + sleep + 0 + tooltip + Returns the unicode value of the indicated character in the string. + + llOverMyLand + arguments ID + tooltip + type key - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip Returns TRUE if id ID over land owned by the script owner, otherwise FALSE.\nReturns TRUE if key ID is over land owned by the object owner, FALSE otherwise. llOwnerSay - energy - 10.0 - sleep - 0.0 - return - void arguments Text + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - says Text to owner only (if owner is in region).\nSays Text to the owner of the object running the script, if the owner has been within the object's simulator since logging into Second Life, regardless of where they may be in-world. + says Text to owner only (if owner is in region).\nSays Text to the owner of the object running the script, if the owner has been within the object's simulator since logging into Second Life, regardless of where they may be in-world. llParcelMediaCommandList - energy - 10.0 - sleep - 2.0 - return - void arguments CommandList - type - list tooltip A list of PARCEL_MEDIA_COMMAND_* flags and their parameters + type + list + energy + 10 + return + void + sleep + 2 tooltip Controls the playback of multimedia resources on a parcel or for an agent, via one or more PARCEL_MEDIA_COMMAND_* arguments specified in CommandList. llParcelMediaQuery - energy - 10.0 - sleep - 2.0 - return - list arguments QueryList + tooltip + type list - tooltip - + energy + 10 + return + list + sleep + 2 tooltip Queries the media properties of the parcel containing the script, via one or more PARCEL_MEDIA_COMMAND_* arguments specified in CommandList.\nThis function will only work if the script is contained within an object owned by the land-owner (or if the land is owned by a group, only if the object has been deeded to the group). llParseString2List - energy - 10.0 - sleep - 0.0 - return - list arguments Text + tooltip + type string - tooltip - Separators + tooltip + type list - tooltip - Spacers + tooltip + type list - tooltip - + energy + 10 + return + list + sleep + 0 tooltip Converts Text into a list, discarding Separators, keeping Spacers (Separators and Spacers must be lists of strings, maximum of 8 each).\nSeparators and Spacers are lists of strings with a maximum of 8 entries each. llParseStringKeepNulls - energy - 10.0 - sleep - 0.0 - return - list arguments Text + tooltip + type string - tooltip - Separators + tooltip + type list - tooltip - Spacers + tooltip + type list - tooltip - + energy + 10 + return + list + sleep + 0 tooltip Breaks Text into a list, discarding separators, keeping spacers, keeping any null values generated. (separators and spacers must be lists of strings, maximum of 8 each).\nllParseStringKeepNulls works almost exactly like llParseString2List, except that if a null is found it will add a null-string instead of discarding it like llParseString2List does. llParticleSystem - energy - 10.0 - sleep - 0.0 - return - void arguments Parameters + tooltip + type list - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Creates a particle system in the prim the script is attached to, based on Parameters. An empty list removes a particle system from object.\nList format is [ rule-1, data-1, rule-2, data-2 ... rule-n, data-n ]. llPassCollisions - energy - 10.0 - sleep - 0.0 - return - void arguments Pass - type - integer tooltip Boolean, if TRUE, collisions are passed from children on to parents. + type + integer + energy + 10 + return + void + sleep + 0 tooltip Configures how collision events are passed to scripts in the linkset.\nIf Pass == TRUE, collisions involving collision-handling scripted child prims are also passed on to the root prim. If Pass == FALSE (default behavior), such collisions will only trigger events in the affected child prim. llPassTouches - energy - 10.0 - sleep - 0.0 - return - void arguments Pass - type - integer tooltip Boolean, if TRUE, touches are passed from children on to parents. + type + integer + energy + 10 + return + void + sleep + 0 tooltip Configures how touch events are passed to scripts in the linkset.\nIf Pass == TRUE, touches involving touch-handling scripted child prims are also passed on to the root prim. If Pass == FALSE (default behavior), such touches will only trigger events in the affected child prim. llPatrolPoints - energy - - sleep - - return - void arguments Points - type - list tooltip A list of vectors for the character to travel through sequentially. The list must contain at least two entries. + type + list Options - type - list tooltip No options available at this time. + type + list + energy + 10 + return + void + sleep + 0 tooltip Patrol a list of points.\nSets the points for a character (llCreateCharacter) to patrol along. llPlaySound + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + energy - 10.0 + 10 + return + void sleep - 0.0 + 0 + tooltip + Plays Sound once, at Volume (0.0 - 1.0) and attached to the object.\nOnly one sound may be attached to an object at a time, and attaching a new sound or calling llStopSound will stop the previously attached sound.\nA second call to llPlaySound with the same sound will not restart the sound, but the new volume will be used, which allows control over the volume of already playing sounds.\nTo restart the sound from the beginning, call llStopSound before calling llPlaySound again. + + llPlaySoundSlave + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + energy + 10 return void + sleep + 0 + tooltip + Plays attached Sound once, at Volume (0.0 - 1.0), synced to next loop of most audible sync master.\nBehaviour is identical to llPlaySound, unless there is a "Sync Master" present. If a Sync Master is already playing, the Slave sound will not be played until the Master hits its loop point and returns to the beginning.\nllPlaySoundSlave will play the sound exactly once; if it is desired to have the sound play every time the Master loops, either use llLoopSoundSlave with extra silence padded on the end of the sound or ensure that llPlaySoundSlave is called at least once per loop of the Master. + + llPow + + arguments + + + Value + + tooltip + + type + float + + + + Exponent + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the Value raised to the power Exponent, or returns 0 and triggers Math Error for imaginary results.\nReturns the Value raised to the Exponent. + + llPreloadSound + arguments Sound + tooltip + type string + + + + energy + 10 + return + void + sleep + 1 + tooltip + Causes nearby viewers to preload the Sound from the object's inventory.\nThis is intended to prevent delays in starting new sounds when called upon. + + llPursue + + arguments + + + TargetID + + tooltip + Agent or object to pursue. + type + key + + + + Options + + tooltip + Parameters for pursuit. + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Chase after a target.\nCauses the character (llCharacter) to pursue the target defined by TargetID. + + llPushObject + + arguments + + + ObjectID + + tooltip + + type + key + + + + Impulse + + tooltip + + type + vector + + + + AngularImpulse + + tooltip + + type + vector + + + + Local + tooltip - + + type + integer + + energy + 10 + return + void + sleep + 0 + tooltip + Applies Impulse and AngularImpulse to ObjectID.\nApplies the supplied impulse and angular impulse to the object specified. + + llReadKeyValue + + arguments + - Volume + Key - type - float tooltip - + + type + string + energy + 10 + return + key + sleep + 0 tooltip - Plays Sound once, at Volume (0.0 - 1.0) and attached to the object.\nOnly one sound may be attached to an object at a time, and attaching a new sound or calling llStopSound will stop the previously attached sound.\nA second call to llPlaySound with the same sound will not restart the sound, but the new volume will be used, which allows control over the volume of already playing sounds.\nTo restart the sound from the beginning, call llStopSound before calling llPlaySound again. + + Starts an asychronous transaction to retrieve the value associated with the key given. Will fail with XP_ERROR_KEY_NOT_FOUND if the key does not exist. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. + - llPlaySoundSlave + llRefreshPrimURL + arguments + energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 20 + tooltip + Reloads the web page shown on the sides of the object. + + llRegionSay + arguments - Sound + Channel - type - string tooltip - + Any integer value except zero. + type + integer - Volume + Text - type - float tooltip - + Message to be transmitted. + type + string + energy + 10 + return + void + sleep + 0 tooltip - Plays attached Sound once, at Volume (0.0 - 1.0), synced to next loop of most audible sync master.\nBehaviour is identical to llPlaySound, unless there is a "Sync Master" present. If a Sync Master is already playing, the Slave sound will not be played until the Master hits its loop point and returns to the beginning.\nllPlaySoundSlave will play the sound exactly once; if it is desired to have the sound play every time the Master loops, either use llLoopSoundSlave with extra silence padded on the end of the sound or ensure that llPlaySoundSlave is called at least once per loop of the Master. + Broadcasts Text to entire region on Channel (except for channel 0). - llPow + llRegionSayTo - energy - 10.0 - sleep - 0.0 - return - float arguments - Value + TargetID - type - float tooltip - + Avatar or object to say to. + type + key - Exponent + Channel + tooltip + Output channel, any integer value. type - float + integer + + + + Text + tooltip - + Message to be transmitted. + type + string - tooltip - Returns the Value raised to the power Exponent, or returns 0 and triggers Math Error for imaginary results.\nReturns the Value raised to the Exponent. - - llPreloadSound - energy - 10.0 - sleep - 1.0 + 10 return void + sleep + 0 + tooltip + Says Text, on Channel, to avatar or object indicated by TargetID (if within region).\nIf TargetID is an avatar and Channel is nonzero, Text can be heard by any attachment on the avatar. + + llReleaseCamera + arguments - Sound + AvatarID - type - string tooltip - + + type + key + deprecated + 1 + energy + 10 + return + void + sleep + 0 tooltip - Causes nearby viewers to preload the Sound from the object's inventory.\nThis is intended to prevent delays in starting new sounds when called upon. + Return camera to agent.\nDeprecated: Use llClearCameraParams instead. - llPursue + llReleaseControls + arguments + energy - - sleep - + 10 return void + sleep + 0 + tooltip + Stop taking inputs.\nStop taking inputs from the avatar. + + llReleaseURL + arguments - TargetID + URL - type - key tooltip - Agent or object to pursue. - - - - Options - + URL to release. type - list - tooltip - Parameters for pursuit. + string - tooltip - Chase after a target.\nCauses the character (llCharacter) to pursue the target defined by TargetID. - - llPushObject - energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + Releases the specified URL, which was previously obtained using llRequestURL. Once released, the URL will no longer be usable. + + llRemoteDataReply + arguments - ObjectID + ChannelID + tooltip + type key - tooltip - - Impulse + MessageID - type - vector tooltip - + + type + key - AngularImpulse + sData - type - vector tooltip - + String data to send + type + string - Local + iData + tooltip + Integer data to send type integer - tooltip - - tooltip - Applies Impulse and AngularImpulse to ObjectID.\nApplies the supplied impulse and angular impulse to the object specified. - - llReadKeyValue - + deprecated + 1 energy - 10.0 - sleep - 0.0 + 10 return - key - arguments - - - Key - - type - string - tooltip - - - - + void + sleep + 3 tooltip - - Starts an asychronous transaction to retrieve the value associated with the key given. Will fail with XP_ERROR_KEY_NOT_FOUND if the key does not exist. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. - + This function is deprecated. - llRefreshPrimURL + llRemoteDataSetRegion + arguments + + deprecated + 1 energy - 10.0 - sleep - 20.0 + 10 return void - arguments - + sleep + 0 tooltip - Reloads the web page shown on the sides of the object. + This function is deprecated. - llRegionSay + llRemoteLoadScriptPin - energy - 10.0 - sleep - 0.0 - return - void arguments - Channel + ObjectID - type - integer tooltip - Any integer value except zero. + Target prim to attempt copying into. + type + key - Text + ScriptName + tooltip + Name of the script in current inventory to copy. type string - tooltip - Message to be transmitted. - - tooltip - Broadcasts Text to entire region on Channel (except for channel 0). - - llRegionSayTo - - energy - 10.0 - sleep - 0.0 - return - void - arguments - - TargetID + PIN - type - key tooltip - Avatar or object to say to. + Integer set on target prim as a Personal Information Number code. + type + integer - Channel + Running + tooltip + If the script should be set running in the target prim. type integer - tooltip - Output channel, any integer value. - Text + StartParameter + tooltip + Integer. Parameter passed to the script if set to be running. type - string + integer + + + + energy + 10 + return + void + sleep + 3 + tooltip + If the owner of the object containing this script can modify the object identified by the specified object key, and if the PIN matches the PIN previously set using llSetRemoteScriptAccessPin (on the target prim), then the script will be copied into target. Running is a boolean specifying whether the script should be enabled once copied into the target object. + + llRemoveFromLandBanList + + arguments + + + AvatarID + tooltip - Message to be transmitted. + + type + key - tooltip - Says Text, on Channel, to avatar or object indicated by TargetID (if within region).\nIf TargetID is an avatar and Channel is nonzero, Text can be heard by any attachment on the avatar. - - llReleaseCamera - - deprecated - true energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0.1000000000000000055511151 + tooltip + Remove avatar from the land ban list.\nRemove specified avatar from the land parcel ban list. + + llRemoveFromLandPassList + arguments AvatarID + tooltip + type key - tooltip - - tooltip - Return camera to agent.\nDeprecated: Use llClearCameraParams instead. - - llReleaseControls - energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0.1000000000000000055511151 tooltip - Stop taking inputs.\nStop taking inputs from the avatar. + Remove avatar from the land pass list.\nRemove specified avatar from the land parcel pass list. - llReleaseURL + llRemoveInventory - energy - 10.0 - sleep - 0.0 - return - void arguments - URL + InventoryItem + tooltip + type string - tooltip - URL to release. - tooltip - Releases the specified URL, which was previously obtained using llRequestURL. Once released, the URL will no longer be usable. - - llRemoteDataReply - - deprecated - true energy - 10.0 - sleep - 3.0 + 10 return void + sleep + 0 + tooltip + Remove the named inventory item.\nRemove the named inventory item from the object inventory. + + llRemoveVehicleFlags + arguments - ChannelID + Vehiclelags - type - key tooltip - + + type + integer + + energy + 10 + return + void + sleep + 0 + tooltip + Removes the enabled bits in 'flags'.\nSets the vehicle flags to FALSE. Valid parameters can be found in the vehicle flags constants section. + + llReplaceAgentEnvironment + + arguments + - MessageID + agent_id + tooltip + type key - tooltip - - sData + transition - type - string tooltip - String data to send + + type + float - iData + environment - type - integer tooltip - Integer data to send + + type + string - tooltip - Send an XML-RPC reply to MessageID on ChannelID with payload of string sData and integer iData. Deprecated: Use HTTP functions/events instead.\nThe size of sData is limited to 254 characters. - - llRemoteDataSetRegion - - deprecated - true energy - 10.0 - sleep - 0.0 + 10 return - void - arguments - + integer + sleep + 0 tooltip - Deprecated: Use HTTP functions/events instead.\nIf an object using remote data channels changes regions, you must call this function to re-register the remote data channels.\nYou do not need to make this call if you don't change regions. + Replaces the entire environment for an agent. Must be used as part of an experience. - llRemoteLoadScriptPin + llReplaceEnvironment - energy - 10.0 - sleep - 3.0 - return - void arguments - ObjectID + position - type - key tooltip - Target prim to attempt copying into. + Location of parcel to change. Use <-1, -1, -1> for entire region. + type + vector - ScriptName + environment + tooltip + + Name of inventory item, or UUID of environment resource to apply. + Use NULL_KEY or empty string to remove environment. + type string - tooltip - Name of the script in current inventory to copy. - PIN + track_no + tooltip + Elevation zone of where to apply environment. Use -1 for all. type integer - tooltip - Integer set on target prim as a Personal Information Number code. - Running + day_length + tooltip + Length of day cycle for this parcel or region. -1 to leave unchanged. type integer - tooltip - If the script should be set running in the target prim. - StartParameter + day_offset + tooltip + Offset from GMT for the day cycle on this parcel or region. -1 to leave unchanged. type integer - tooltip - Integer. Parameter passed to the script if set to be running. + energy + 10 + return + integer + sleep + 0 tooltip - If the owner of the object containing this script can modify the object identified by the specified object key, and if the PIN matches the PIN previously set using llSetRemoteScriptAccessPin (on the target prim), then the script will be copied into target. Running is a boolean specifying whether the script should be enabled once copied into the target object. + Replaces the environment for a parcel or region. - llRemoveFromLandBanList + llReplaceSubString - energy - 10.0 - sleep - 0.0 - return - void arguments - AvatarID + InitialString - type - key tooltip - + The original string in which to hunt for substring matches. + type + string - - tooltip - Remove avatar from the land ban list.\nRemove specified avatar from the land parcel ban list. - - llRemoveFromLandPassList - - energy - 10.0 - sleep - 0.0 - return - void - arguments - - AvatarID + SubString - type - key tooltip - + The original substring to find. + type + string - - tooltip - Remove avatar from the land pass list.\nRemove specified avatar from the land parcel pass list. - - llRemoveInventory - - energy - 10.0 - sleep - 0.0 - return - void - arguments - - InventoryItem + NewSubString + tooltip + The new substring used to replace. type string - tooltip - - - tooltip - Remove the named inventory item.\nRemove the named inventory item from the object inventory. - - llRemoveVehicleFlags - - energy - 10.0 - sleep - 0.0 - return - void - arguments - - Vehiclelags + Count + tooltip + The max number of replacements to make. Zero Count means "replace all". Positive Count moves left to right. Negative moves right to left. type integer - tooltip - + energy + 10 + return + string + sleep + 0 tooltip - Removes the enabled bits in 'flags'.\nSets the vehicle flags to FALSE. Valid parameters can be found in the vehicle flags constants section. + Searches InitialString and replaces instances of SubString with NewSubString. Zero Count means "replace all". Positive Count moves left to right. Negative moves right to left. llRequestAgentData - energy - 10.0 - sleep - 0.1 - return - key arguments AvatarID + tooltip + type key - tooltip - Data + tooltip + type integer - tooltip - + energy + 10 + return + key + sleep + 0.1000000000000000055511151 tooltip Requests data about AvatarID. When data is available the dataserver event will be raised.\nThis function requests data about an avatar. If and when the information is collected, the dataserver event is triggered with the key returned from this function passed in the requested parameter. See the agent data constants (DATA_*) for details about valid values of data and what each will return in the dataserver event. llRequestDisplayName - energy - 10.0 - sleep - 0.0 - return - key arguments AvatarID - type - key tooltip Avatar UUID + type + key + energy + 10 + return + key + sleep + 0 tooltip Requests the display name of the agent. When the display name is available the dataserver event will be raised.\nThe avatar identified does not need to be in the same region or online at the time of the request.\nReturns a key that is used to identify the dataserver event when it is raised. llRequestExperiencePermissions - energy - 10.0 - sleep - 0.0 - return - void arguments - - AgentID - - type - key - tooltip - - - - - unused - - type - string - tooltip - Not used, should be "" - - + + AgentID + + tooltip + + type + key + + + + unused + + tooltip + Not used, should be "" + type + string + + + energy + 10 + return + void + sleep + 0 tooltip Ask the agent for permission to participate in an experience. This request is similar to llRequestPermissions with the following permissions: PERMISSION_TAKE_CONTROLS, PERMISSION_TRIGGER_ANIMATION, PERMISSION_ATTACH, PERMISSION_TRACK_CAMERA, PERMISSION_CONTROL_CAMERA and PERMISSION_TELEPORT. However, unlike llRequestPermissions the decision to allow or block the request is persistent and applies to all scripts using the experience grid wide. Subsequent calls to llRequestExperiencePermissions from scripts in the experience will receive the same response automatically with no user interaction. One of experience_permissions or experience_permissions_denied will be generated in response to this call. Outstanding permission requests will be lost if the script is derezzed, moved to another region or reset. @@ -14842,3967 +19494,4479 @@ llRequestInventoryData - energy - 10.0 - sleep - 1.0 - return - key arguments InventoryItem + tooltip + type string - tooltip - - tooltip - Requests data for the named InventoryItem.\nWhen data is available, the dataserver event will be raised with the key returned from this function in the requested parameter.\nThe only request currently implemented is to request data from landmarks, where the data returned is in the form "<float, float, float>" which can be cast to a vector. This position is in region local coordinates. - - llRequestPermissions - energy - 10.0 - sleep - 0.0 + 10 return - void + key + sleep + 1 + tooltip + Requests data for the named InventoryItem.\nWhen data is available, the dataserver event will be raised with the key returned from this function in the requested parameter.\nThe only request currently implemented is to request data from landmarks, where the data returned is in the form "<float, float, float>" which can be cast to a vector. This position is in region local coordinates. + + llRequestPermissions + arguments AvatarID + tooltip + type key - tooltip - PermissionMask + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Ask AvatarID to allow the script to perform certain actions, specified in the PermissionMask bitmask. PermissionMask should be one or more PERMISSION_* constants. Multiple permissions can be requested simultaneously by ORing the constants together. Many of the permissions requests can only go to object owner.\nThis call will not stop script execution. If the avatar grants the requested permissions, the run_time_permissions event will be called. llRequestSecureURL + arguments + energy - 10.0 - sleep - 0.0 + 10 return key - arguments - + sleep + 0 tooltip Requests one HTTPS:// (SSL) URL for use by this object. The http_request event is triggered with results.\nReturns a key that is the handle used for identifying the request in the http_request event. llRequestSimulatorData - energy - 10.0 - sleep - 1.0 - return - key arguments RegionName + tooltip + type string - tooltip - Data + tooltip + type integer - tooltip - + energy + 10 + return + key + sleep + 1 tooltip Requests the specified Data about RegionName. When the specified data is available, the dataserver event is raised.\nData should use one of the DATA_SIM_* constants.\nReturns a dataserver query ID and triggers the dataserver event when data is found. llRequestURL + arguments + energy - 10.0 - sleep - 0.0 + 10 return key - arguments - + sleep + 0 tooltip Requests one HTTP:// URL for use by this script. The http_request event is triggered with the result of the request.\nReturns a key that is the handle used for identifying the result in the http_request event. - llRequestUsername + llRequestUserKey + arguments + + + Name + + tooltip + Name of agent to look up. + type + string + + + energy - 10.0 - sleep - 0.0 + 10 return key + sleep + 0 + tooltip + Look up Agent ID for the named agent using a historical name. + + llRequestUsername + arguments AvatarID + tooltip + type key - tooltip - + energy + 10 + return + key + sleep + 0 tooltip Requests single-word user-name of an avatar. When data is available the dataserver event will be raised.\nRequests the user-name of the identified agent. When the user-name is available the dataserver event is raised.\nThe agent identified does not need to be in the same region or online at the time of the request.\nReturns a key that is used to identify the dataserver event when it is raised. llResetAnimationOverride - energy - 0 - sleep - 0 - return - void arguments AnimationState + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Resets the animation of the specified animation state to the default value.\nIf animation state equals "ALL", then all animation states are reset. + Resets the animation of the specified animation state to the default value.\nIf animation state equals "ALL", then all animation states are reset. llResetLandBanList + arguments + energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0.1000000000000000055511151 tooltip Removes all residents from the land ban list. llResetLandPassList + arguments + energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0.1000000000000000055511151 tooltip Removes all residents from the land access/pass list. llResetOtherScript - energy - 10.0 - sleep - 0.0 - return - void arguments ScriptName + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Resets the named script. llResetScript + arguments + energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0 tooltip Resets the script. llResetTime + arguments + energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0 tooltip Sets the time to zero.\nSets the internal timer to zero. llReturnObjectsByID - energy - 10.0 - sleep - 0.0 - return - integer arguments ObjectIDs - type - list tooltip List of object UUIDs to be returned. + type + list + energy + 10 + return + integer + sleep + 0 tooltip Return objects using their UUIDs.\nRequires the PERMISSION_RETURN_OBJECTS permission and that the script owner owns the parcel the returned objects are in, or is an estate manager or region owner. llReturnObjectsByOwner - energy - 10.0 - sleep - 0.0 - return - integer arguments ID + tooltip + Object owner's UUID. type key - tooltip - Object owner's UUID. Scope + tooltip + type integer - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip Return objects based upon their owner and a scope of parcel, parcel owner, or region.\nRequires the PERMISSION_RETURN_OBJECTS permission and that the script owner owns the parcel the returned objects are in, or is an estate manager or region owner. llRezAtRoot - energy - 200.0 - sleep - 0.1 - return - void arguments InventoryItem + tooltip + type string - tooltip - Position + tooltip + type vector - tooltip - Velocity + tooltip + type vector - tooltip - Rotation + tooltip + type rotation - tooltip - StartParameter + tooltip + type integer - tooltip - - tooltip - Instantiate owner's InventoryItem at Position with Velocity, Rotation and with StartParameter. The last selected root object's location will be set to Position.\nCreates object's inventory item at the given Position, with Velocity, Rotation, and StartParameter. - - llRezObject - energy 200 - sleep - 0.1 return void + sleep + 0.1000000000000000055511151 + tooltip + Instantiate owner's InventoryItem at Position with Velocity, Rotation and with StartParameter. The last selected root object's location will be set to Position.\nCreates object's inventory item at the given Position, with Velocity, Rotation, and StartParameter. + + llRezObject + arguments InventoryItem + tooltip + type string - tooltip - Position + tooltip + type vector - tooltip - Velocity + tooltip + type vector - tooltip - Rotation + tooltip + type rotation - tooltip - StartParameter + tooltip + type integer - tooltip - + energy + 200 + return + void + sleep + 0.1000000000000000055511151 tooltip - Instantiate owners InventoryItem at Position with Velocity, Rotation and with start StartParameter.\nCreates object's inventory item at Position with Velocity and Rotation supplied. The StartParameter value will be available to the newly created object in the on_rez event or through the llGetStartParameter function.\nThe Velocity parameter is ignored if the rezzed object is not physical. + Instantiate owners InventoryItem at Position with Velocity, Rotation and with start StartParameter.\nCreates object's inventory item at Position with Velocity and Rotation supplied. The StartParameter value will be available to the newly created object in the on_rez event or through the llGetStartParameter function.\nThe Velocity parameter is ignored if the rezzed object is not physical. - llRot2Angle + llRezObjectWithParams - energy - 10.0 - sleep - 0.0 - return - float arguments - Rotation + InventoryItem + tooltip + type - rotation + string + + + + Parms + tooltip - + + type + list + energy + 200 + return + key + sleep + 0.1000000000000000055511151 tooltip - Returns the rotation angle represented by Rotation.\nReturns the angle represented by the Rotation. + Instantiate owner's InventoryItem with the given parameters. - llRot2Axis + llRot2Angle - energy - 10.0 - sleep - 0.0 - return - vector arguments Rotation + tooltip + type rotation - tooltip - + energy + 10 + return + float + sleep + 0 tooltip - Returns the rotation axis represented by Rotation.\nReturns the axis represented by the Rotation. + Returns the rotation angle represented by Rotation.\nReturns the angle represented by the Rotation. - llRot2Euler + llRot2Axis - energy - 10.0 - sleep - 0.0 - return - vector arguments Rotation + tooltip + type rotation - tooltip - - tooltip - Returns the Euler representation (roll, pitch, yaw) of Rotation.\nReturns the Euler Angle representation of the Rotation. - - llRot2Fwd - energy - 10.0 - sleep - 0.0 + 10 return vector + sleep + 0 + tooltip + Returns the rotation axis represented by Rotation.\nReturns the axis represented by the Rotation. + + llRot2Euler + arguments Rotation + tooltip + type rotation - tooltip - - tooltip - Returns the forward vector defined by Rotation.\nReturns the forward axis represented by the Rotation. - - llRot2Left - energy - 10.0 - sleep - 0.0 + 10 return vector + sleep + 0 + tooltip + Returns the Euler representation (roll, pitch, yaw) of Rotation.\nReturns the Euler Angle representation of the Rotation. + + llRot2Fwd + arguments Rotation + tooltip + type rotation - tooltip - - tooltip - Returns the left vector defined by Rotation.\nReturns the left axis represented by the Rotation. - - llRot2Up - energy - 10.0 - sleep - 0.0 + 10 return vector + sleep + 0 + tooltip + Returns the forward vector defined by Rotation.\nReturns the forward axis represented by the Rotation. + + llRot2Left + arguments Rotation + tooltip + type rotation - tooltip - + energy + 10 + return + vector + sleep + 0 tooltip - Returns the up vector defined by Rotation.\nReturns the up axis represented by the Rotation. + Returns the left vector defined by Rotation.\nReturns the left axis represented by the Rotation. - llRotateTexture + llRot2Up - energy - 10.0 - sleep - 0.2 - return - void arguments - Radians + Rotation - type - float tooltip - - - - - Face - + type - integer - tooltip - + rotation + energy + 10 + return + vector + sleep + 0 tooltip - Sets the texture rotation for the specified Face to angle Radians.\nIf Face is ALL_SIDES, rotates the texture of all sides. + Returns the up vector defined by Rotation.\nReturns the up axis represented by the Rotation. llRotBetween - energy - 10.0 - sleep - 0.0 - return - rotation arguments Vector1 + tooltip + type vector - tooltip - Vector2 + tooltip + type vector - tooltip - + energy + 10 + return + rotation + sleep + 0 tooltip Returns the rotation to rotate Vector1 to Vector2.\nReturns the rotation needed to rotate Vector1 to Vector2. llRotLookAt - energy - 10.0 - sleep - 0.0 - return - void arguments Rotation + tooltip + type rotation - tooltip - Strength + tooltip + type float - tooltip - Damping + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Cause object to rotate to Rotation, with a force function defined by Strength and Damping parameters. Good strength values are around half the mass of the object and good damping values are less than 1/10th of the strength.\nAsymmetrical shapes require smaller damping.\nA strength of 0.0 cancels the look at. llRotTarget - energy - 10.0 - sleep - 0.0 - return - integer arguments Rotation + tooltip + type rotation - tooltip - LeeWay + tooltip + type float - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip Set rotations with error of LeeWay radians as a rotational target, and return an ID for the rotational target.\nThe returned number is a handle that can be used in at_rot_target and llRotTargetRemove. llRotTargetRemove - energy - 10.0 - sleep - 0.0 - return - void arguments Handle + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Removes rotational target number.\nRemove rotational target indicated by the handle. - llRound + llRotateTexture + arguments + + + Radians + + tooltip + + type + float + + + + Face + + tooltip + + type + integer + + + energy - 10.0 - sleep - 0.0 + 10 return - integer + void + sleep + 0.2000000000000000111022302 + tooltip + Sets the texture rotation for the specified Face to angle Radians.\nIf Face is ALL_SIDES, rotates the texture of all sides. + + llRound + arguments Value + tooltip + type float - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip Returns Value rounded to the nearest integer.\nReturns the Value rounded to the nearest integer. - llSameGroup + llSHA1String + arguments + + + Text + + tooltip + + type + string + + + energy - 10.0 + 10 + return + string sleep - 0.0 + 0 + tooltip + Returns a string of 40 hex characters that is the SHA1 security hash of text. + + llSHA256String + + arguments + + + text + + tooltip + + type + string + + + + energy + 10 return - integer + string + sleep + 0 + tooltip + Returns a string of 64 hex characters that is the SHA256 security hash of text. + + llSameGroup + arguments ID + tooltip + type key - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip Returns TRUE if avatar ID is in the same region and has the same active group, otherwise FALSE.\nReturns TRUE if the object or agent identified is in the same simulator and has the same active group as this object. Otherwise, returns FALSE. llSay - energy - 10.0 - sleep - 0.0 - return - void arguments Channel - type - integer tooltip Channel to use to say text on. + type + integer Text - type - string tooltip Text to say. + type + string + energy + 10 + return + void + sleep + 0 tooltip Says Text on Channel.\nThis chat method has a range of 20m radius.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. llScaleByFactor - energy - 10.0 - sleep - 0.0 - return - integer arguments ScalingFactor - type - float tooltip The multiplier to be used with the prim sizes and their local positions. + type + float + energy + 10 + return + integer + sleep + 0 tooltip Attempts to resize the entire object by ScalingFactor, maintaining the size-position ratios of the prims.\n\nResizing is subject to prim scale limits and linkability limits. This function can not resize the object if the linkset is physical, a pathfinding character, in a keyframed motion, or if resizing would cause the parcel to overflow.\nReturns a boolean (an integer) TRUE if it succeeds, FALSE if it fails. llScaleTexture - energy - 10.0 - sleep - 0.2 - return - void arguments Horizontal + tooltip + type float - tooltip - Vertical + tooltip + type float - tooltip - Face + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0.2000000000000000111022302 tooltip Sets the diffuse texture Horizontal and Vertical repeats on Face of the prim the script is attached to.\nIf Face == ALL_SIDES, all sides are set in one call.\nNegative values for horizontal and vertical will flip the texture. llScriptDanger - energy - 10.0 - sleep - 0.0 - return - integer arguments Position + tooltip + type vector - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip - Returns TRUE if Position is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts.\nReturns true if the position is over public land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts. + Returns TRUE if Position is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts.\nReturns true if the position is over public land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts. llScriptProfiler - energy - 10.0 - sleep - 0.0 - return - void arguments State - type - integer tooltip PROFILE_NONE or PROFILE_SCRIPT_MEMORY flags to control the state. + type + integer + energy + 10 + return + void + sleep + 0 tooltip Enables or disables script profiling options. Currently only supports PROFILE_SCRIPT_MEMORY (Mono only) and PROFILE_NONE.\nMay significantly reduce script performance. llSendRemoteData - deprecated - true - energy - 10.0 - sleep - 3.0 - return - key arguments ChannelID + tooltip + type key - tooltip - Destination + tooltip + type string - tooltip - Value + tooltip + type integer - tooltip - Text + tooltip + type string - tooltip - + deprecated + 1 + energy + 10 + return + key + sleep + 3 tooltip - Deprecated: use HTTP functions and events instead.\nSends an XML-RPC request to Destination through ChannelID with payload of ChannelID (in a string), integer Value and string Text.\nReturns a key that is the message_id for the resulting remote_data events. + This function is deprecated. llSensor - energy - 10.0 - sleep - 0.0 - return - void arguments Name - type - string tooltip Object or avatar name. + type + string ID - type - key tooltip Object or avatar UUID. + type + key Type - type - integer tooltip Bit-field mask of AGENT, AGENT_BY_LEGACY_NAME, AGENT_BY_USERNAME, ACTIVE, PASSIVE, and/or SCRIPTED + type + integer Range - type - float tooltip Distance to scan. 0.0 - 96.0m. + type + float Arc - type - float tooltip Angle, in radians, from the local x-axis of the prim to scan. + type + float + energy + 10 + return + void + sleep + 0 tooltip Performs a single scan for Name and ID with Type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within Range meters and Arc radians of forward vector.\nSpecifying a blank Name, 0 Type, or NULL_KEY ID will prevent filtering results based on that parameter. A range of 0.0 does not perform a scan.\nResults are returned in the sensor and no_sensor events. llSensorRemove + arguments + energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0 tooltip removes sensor.\nRemoves the sensor set by llSensorRepeat. llSensorRepeat - energy - 10.0 - sleep - 0.0 - return - void arguments Name - type - string tooltip Object or avatar name. + type + string ID - type - key tooltip Object or avatar UUID. + type + key Type - type - integer tooltip Bit-field mask of AGENT, AGENT_BY_LEGACY_NAME, AGENT_BY_USERNAME, ACTIVE, PASSIVE, and/or SCRIPTED + type + integer Range - type - float tooltip Distance to scan. 0.0 - 96.0m. + type + float Arc - type - float tooltip Angle, in radians, from the local x-axis of the prim to scan. + type + float Rate - type - float tooltip Period, in seconds, between scans. + type + float + energy + 10 + return + void + sleep + 0 tooltip Initiates a periodic scan every Rate seconds, for Name and ID with Type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within Range meters and Arc radians of forward vector.\nSpecifying a blank Name, 0 Type, or NULL_KEY ID will prevent filtering results based on that parameter. A range of 0.0 does not perform a scan.\nResults are returned in the sensor and no_sensor events. - llSetAlpha + llSetAgentEnvironment + arguments + + + agent_id + + tooltip + Agent to receive new environment settings. + type + key + + + + transition + + tooltip + Number of seconds over which to apply new settings. + type + float + + + + Settings + + tooltip + List of environment settings to replace for agent. + type + list + + + energy - 10.0 + 10 + return + integer sleep - 0.0 + 0 + tooltip + Sets an agent's environmental values to the specified values. Must be used as part of an experience. + + llSetAgentRot + + arguments + + + rot + + tooltip + Rotation to turn the avatar to face. + type + rotation + + + + flags + + tooltip + flags + type + integer + + + + energy + 10 return void + sleep + 0 + tooltip + Sets the avatar rotation to the given value. + + llSetAlpha + arguments Opacity + tooltip + type float - tooltip - Face + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets the alpha (opacity) of Face.\nSets the alpha (opacity) value for Face. If Face is ALL_SIDES, sets the alpha for all faces. The alpha value is interpreted as an opacity percentage (1.0 is fully opaque, and 0.2 is mostly transparent). This function will clamp alpha values less than 0.1 to 0.1 and greater than 1.0 to 1. llSetAngularVelocity - energy - - sleep - 0.0 - return - void arguments AngVel - type - vector tooltip The angular velocity to set the object to. + type + vector Local - type - integer tooltip If TRUE, the AngVel is treated as a local directional vector instead of a regional directional vector. + type + integer + energy + 10 + return + void + sleep + 0 tooltip - Sets an object's angular velocity to AngVel, in local coordinates if Local == TRUE (if the script is physical).\nHas no effect on non-physical objects. + Sets an object's angular velocity to AngVel, in local coordinates if Local == TRUE (if the script is physical).\nHas no effect on non-physical objects. llSetAnimationOverride - energy - 0 - sleep - 0 - return - void arguments AnimationState + tooltip + type string - tooltip - AnimationName + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets the animation (in object inventory) that will play for the given animation state.\nTo use this function the script must obtain the PERMISSION_OVERRIDE_ANIMATIONS permission. llSetBuoyancy - energy - 10.0 - sleep - 0.0 - return - void arguments Buoyancy + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Set the tasks buoyancy (0 is none, < 1.0 sinks, 1.0 floats, > 1.0 rises).\nSet the object buoyancy. A value of 0 is none, less than 1.0 sinks, 1.0 floats, and greater than 1.0 rises. llSetCameraAtOffset - energy - 10.0 - sleep - 0.0 - return - void arguments Offset + tooltip + type vector - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Sets the camera used in this object, at offset, if an avatar sits on it.\nSets the offset that an avatar's camera will be moved to if the avatar sits on the object. + Sets the camera used in this object, at offset, if an avatar sits on it.\nSets the offset that an avatar's camera will be moved to if the avatar sits on the object. llSetCameraEyeOffset - energy - 10.0 - sleep - 0.0 - return - void arguments Offset + tooltip + type vector - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets the camera eye offset used in this object if an avatar sits on it. llSetCameraParams - energy - 10.0 - sleep - 0.0 - return - void arguments Parameters + tooltip + type list - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets multiple camera parameters at once. List format is [ rule-1, data-1, rule-2, data-2 . . . rule-n, data-n ]. llSetClickAction - energy - 10.0 - sleep - 0.0 - return - void arguments Action - type - integer tooltip A CLICK_ACTION_* flag + type + integer + energy + 10 + return + void + sleep + 0 tooltip Sets the action performed when a prim is clicked upon. llSetColor - energy - 10.0 - sleep - 0.0 - return - void arguments Color + tooltip + type vector - tooltip - Face + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets the color, for the face.\nSets the color of the side specified. If Face is ALL_SIDES, sets the color on all faces. llSetContentType - energy - - sleep - - return - void arguments HTTPRequestID + tooltip + A valid http_request() key type key + + + + ContentType + tooltip - A valid http_request() key + Media type to use with any following llHTTPResponse(HTTPRequestID, ...) + type + integer + + energy + 10 + return + void + sleep + 0 + tooltip + Set the media type of an LSL HTTP server response to ContentType.\nHTTPRequestID must be a valid http_request ID. ContentType must be one of the CONTENT_TYPE_* constants. + + llSetDamage + + arguments + - ContentType + Damage - type - integer tooltip - Media type to use with any following llHTTPResponse(HTTPRequestID, ...) + + type + float - tooltip - Set the media type of an LSL HTTP server response to ContentType.\nHTTPRequestID must be a valid http_request ID. ContentType must be one of the CONTENT_TYPE_* constants. - - llSetDamage - energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + Sets the amount of damage that will be done to an avatar that this task hits. Task will be killed.\nSets the amount of damage that will be done to an avatar that this object hits. This object will be destroyed on damaging an avatar, and no collision event is triggered. + + llSetEnvironment + arguments - Damage + Position + tooltip + Location within the region. type - float + vector + + + + EnvParams + tooltip - + List of environment settings to change for the specified parcel location. + type + list + energy + 10 + return + integer + sleep + 0 tooltip - Sets the amount of damage that will be done to an avatar that this task hits. Task will be killed.\nSets the amount of damage that will be done to an avatar that this object hits. This object will be destroyed on damaging an avatar, and no collision event is triggered. + Returns a string with the requested data about the region. llSetForce - energy - 10.0 - sleep - 0.0 - return - void arguments Force - type - vector tooltip Directional force. + type + vector Local - type - integer tooltip Boolean, if TRUE uses local axis, if FALSE uses region axis. + type + integer + energy + 10 + return + void + sleep + 0 tooltip Sets Force on object, in object-local coordinates if Local == TRUE (otherwise, the region reference frame is used).\nOnly works on physical objects. llSetForceAndTorque - energy - 10.0 - sleep - 0.0 - return - void arguments Force - type - vector tooltip Directional force. + type + vector Torque - type - vector tooltip Torque force. + type + vector Local - type - integer tooltip Boolean, if TRUE uses local axis, if FALSE uses region axis. + type + integer + energy + 10 + return + void + sleep + 0 tooltip Sets the Force and Torque of object, in object-local coordinates if Local == TRUE (otherwise, the region reference frame is used).\nOnly works on physical objects. - llSetHoverHeight + llSetGroundTexture + arguments + + + Changes + + tooltip + A list of ground texture properties to change. + type + list + + + energy - 10.0 - sleep - 0.0 + 10 return - void + integer + sleep + 0 + tooltip + Changes terrain texture properties in the region. + + llSetHoverHeight + arguments Height - type - float tooltip Distance above the ground. + type + float Water - type - integer tooltip Boolean, if TRUE then hover above water too. + type + integer Tau - type - float tooltip Seconds to critically damp in. + type + float + energy + 10 + return + void + sleep + 0 tooltip Critically damps a physical object to a Height (either above ground level or above the higher of land and water if water == TRUE).\nDo not use with vehicles. Use llStopHover to stop hovering. llSetInventoryPermMask - god-mode - true - energy - 10.0 - sleep - 0.0 - return - void arguments InventoryItem + tooltip + An item in the prim's inventory type string - tooltip - An item in the prim's inventory PermissionFlag - type - integer tooltip MASK_* flag + type + integer PermissionMask - type - integer tooltip Permission bit-field (PERM_* flags) + type + integer + energy + 10 + god-mode + 1 + return + void + sleep + 0 tooltip Sets the given permission mask to the new value on the inventory item. llSetKeyframedMotion - energy - - sleep - - return - void arguments Keyframes - type - list tooltip Strided keyframe list of the form: position, orientation, time. Each keyframe is interpreted relative to the previous transform of the object. + type + list Options + tooltip + type list - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Requests that a non-physical object be key-framed according to key-frame list.\nSpecify a list of times, positions, and orientations to be followed by an object. The object will be smoothly moved between key-frames by the simulator. Collisions with other non-physical or key-framed objects will be ignored (no script events will fire and collision processing will not occur). Collisions with physical objects will be computed and reported, but the key-framed object will be unaffected by those collisions.\nKeyframes is a strided list containing positional, rotational, and time data for each step in the motion. Options is a list containing optional arguments and parameters (specified by KFM_* constants). llSetLinkAlpha - energy - 10.0 - sleep - 0.0 - return - void arguments LinkNumber + tooltip + type integer - tooltip - Opacity + tooltip + type float - tooltip - Face + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip If a prim exists in the link chain at LinkNumber, set Face to Opacity.\nSets the Face, on the linked prim specified, to the Opacity. llSetLinkCamera - energy - 10.0 - sleep - 0.0 - return - void arguments LinkNumber - type - integer tooltip Prim link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer EyeOffset + tooltip + Offset, relative to the object's centre and expressed in local coordinates, that the camera looks from. type vector - tooltip - Offset, relative to the object's centre and expressed in local coordinates, that the camera looks from. LookOffset + tooltip + Offset, relative to the object's centre and expressed in local coordinates, that the camera looks toward. type vector - tooltip - Offset, relative to the object's centre and expressed in local coordinates, that the camera looks toward. + energy + 10 + return + void + sleep + 0 tooltip Sets the camera eye offset, and the offset that camera is looking at, for avatars that sit on the linked prim. llSetLinkColor + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + + + + Color + + tooltip + Color in RGB <R.R, G.G, B.B> + type + vector + + + + Face + + tooltip + Side number or ALL_SIDES. + type + integer + + + energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + If a task exists in the link chain at LinkNumber, set the Face to color.\nSets the color of the linked child's side, specified by LinkNumber. + + llSetLinkMedia + + arguments + + + Link + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims). + type + integer + + + + Face + + tooltip + Face number. + type + integer + + + + Parameters + + tooltip + A set of name/value pairs (in no particular order) + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Set the media parameters for a particular face on linked prim, specified by Link. Returns an integer that is a STATUS_* flag which details the success/failure of the operation(s).\nMediaParameters is a set of name/value pairs in no particular order. Parameters not specified are unchanged, or if new media is added then set to the default specified. + + llSetLinkPrimitiveParams + arguments LinkNumber + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag type integer - tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. - Color + Parameters - type - vector tooltip - Color in RGB <R.R, G.G, B.B> - - - - Face - + type - integer - tooltip - Side number or ALL_SIDES. + list + energy + 10 + return + void + sleep + 0.2000000000000000111022302 tooltip - If a task exists in the link chain at LinkNumber, set the Face to color.\nSets the color of the linked child's side, specified by LinkNumber. + Set primitive parameters for LinkNumber based on Parameters.\nSets the parameters (or properties) of any linked prim in one step. - llSetLinkMedia + llSetLinkPrimitiveParamsFast - energy - 0.0 - sleep - 0.0 - return - integer arguments - Link + LinkNumber - type - integer tooltip - Link number (0: unlinked, 1: root prim, >1: child prims). - - - - Face - + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag type integer - tooltip - Face number. Parameters + tooltip + type list - tooltip - A set of name/value pairs (in no particular order) - tooltip - Set the media parameters for a particular face on linked prim, specified by Link. Returns an integer that is a STATUS_* flag which details the success/failure of the operation(s).\nMediaParameters is a set of name/value pairs in no particular order. Parameters not specified are unchanged, or if new media is added then set to the default specified. - - llSetLinkPrimitiveParams - energy - 10.0 - sleep - 0.2 + 10 return void + sleep + 0 + tooltip + Set primitive parameters for LinkNumber based on Parameters, without a delay.\nSet parameters for link number, from the list of Parameters, with no built-in script sleep. This function is identical to llSetLinkPrimitiveParams, except without the delay. + + llSetLinkRenderMaterial + arguments LinkNumber + tooltip + type integer - tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag - Parameters + RenderMaterial + tooltip + type - list + string + + + + Face + tooltip - + + type + integer - tooltip - Set primitive parameters for LinkNumber based on Parameters.\nSets the parameters (or properties) of any linked prim in one step. - - llSetLinkPrimitiveParamsFast - energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0.2000000000000000111022302 + tooltip + Sets the Render Material of Face on a linked prim, specified by LinkNumber. Render Materail may be a UUID or name of a material in prim inventory. + + llSetLinkSitFlags + arguments LinkNumber + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. type integer - tooltip - Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag - Parameters + Flags - type - list tooltip - + The new set of sit flags to apply to the specified prims in this linkset. + type + integer + energy + 10 + return + void + sleep + 0 tooltip - Set primitive parameters for LinkNumber based on Parameters, without a delay.\nSet parameters for link number, from the list of Parameters, with no built-in script sleep. This function is identical to llSetLinkPrimitiveParams, except without the delay. + Returns the sit flags set on the specified prim in a linkset. llSetLinkTexture - energy - 10.0 - sleep - 0.2 - return - void arguments LinkNumber + tooltip + type integer - tooltip - Texture + tooltip + type string - tooltip - Face + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0.2000000000000000111022302 tooltip Sets the Texture of Face on a linked prim, specified by LinkNumber. Texture may be a UUID or name of a texture in prim inventory. llSetLinkTextureAnim - energy - 10.0 - sleep - 0.0 - return - void arguments LinkNumber - type - integer tooltip Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag to effect + type + integer Mode - type - integer tooltip Bitmask of animation options. + type + integer Face - type - integer tooltip Specifies which object face to animate or ALL_SIDES. + type + integer SizeX - type - integer tooltip Horizontal frames (ignored for ROTATE and SCALE). + type + integer SizeY - type - integer tooltip Vertical frames (ignored for ROTATE and SCALE). + type + integer Start - type - float tooltip Start position/frame number (or radians for ROTATE). + type + float Length - type - float tooltip Specifies the animation duration, in frames (or radians for ROTATE). + type + float Rate - type - float tooltip Specifies the animation playback rate, in frames per second (must be greater than zero). + type + float + energy + 10 + return + void + sleep + 0 tooltip Animates a texture on the prim specified by LinkNumber, by setting the texture scale and offset.\nMode is a bitmask of animation options.\nFace specifies which object face to animate.\nSizeX and SizeY specify the number of horizontal and vertical frames.Start specifes the animation start point.\nLength specifies the animation duration.\nRate specifies the animation playback rate. llSetLocalRot - energy - 10.0 - sleep - 0.2 - return - void arguments Rotation + tooltip + type rotation - tooltip - + energy + 10 + return + void + sleep + 0.2000000000000000111022302 tooltip Sets the rotation of a child prim relative to the root prim. llSetMemoryLimit - energy - 10.0 - sleep - 0.0 - return - integer arguments Limit - type - integer tooltip The amount to reserve, which must be less than the allowed maximum (currently 64KB) and not already have been exceeded. + type + integer + energy + 10 + return + integer + sleep + 0 tooltip Requests Limit bytes to be reserved for this script.\nReturns TRUE or FALSE indicating whether the limit was set successfully.\nThis function has no effect if the script is running in the LSO VM. llSetObjectDesc - energy - 10.0 - sleep - 0.0 - return - void arguments Description + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets the description of the prim to Description.\nThe description field is limited to 127 characters. llSetObjectName - energy - 10.0 - sleep - 0.0 - return - void arguments Name + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Sets the prim's name to Name. + Sets the prim's name to Name. llSetObjectPermMask - god-mode - true - energy - 10.0 - sleep - 0.0 - return - void arguments PermissionFlag - type - integer tooltip MASK_* flag + type + integer PermissionMask - type - integer tooltip Permission bit-field (PERM_* flags) + type + integer + energy + 10 + god-mode + 1 + return + void + sleep + 0 tooltip Sets the specified PermissionFlag permission to the value specified by PermissionMask on the object the script is attached to. llSetParcelMusicURL - energy - 10.0 - sleep - 2.0 - return - void arguments URL + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 2 tooltip Sets the streaming audio URL for the parcel the object is on.\nThe object must be owned by the owner of the parcel; if the parcel is group owned the object must be owned by that group. llSetPayPrice - energy - 10.0 - sleep - 0.0 - return - void arguments Price - type - integer tooltip The default price shown in the textu input field. + type + integer QuickButtons + tooltip + Specifies the 4 payment values shown in the payment dialog's buttons (or PAY_HIDE). type list - tooltip - Specifies the 4 payment values shown in the payment dialog's buttons (or PAY_HIDE). + energy + 10 + return + void + sleep + 0 tooltip - Sets the default amount when someone chooses to pay this object.\nPrice is the default price shown in the textu input field. QuickButtons specifies the 4 payment values shown in the payment dialog's buttons.\nInput field and buttons may be hidden with PAY_HIDE constant, and may be set to their default values using PAY_DEFAULT. + Sets the default amount when someone chooses to pay this object.\nPrice is the default price shown in the textu input field. QuickButtons specifies the 4 payment values shown in the payment dialog's buttons.\nInput field and buttons may be hidden with PAY_HIDE constant, and may be set to their default values using PAY_DEFAULT. llSetPhysicsMaterial - energy - - sleep - - return - void arguments MaterialBits - type - integer tooltip A bitmask specifying which of the parameters in the other arguments should be applied to the object. + type + integer GravityMultiplier + tooltip + type float - tooltip - Restitution + tooltip + type float - tooltip - Friction + tooltip + type float - tooltip - Density + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Sets the selected parameters of the object's physics behavior.\nMaterialBits is a bitmask specifying which of the parameters in the other arguments should be applied to the object. GravityMultiplier, Restitution, Friction, and Density are the possible parameters to manipulate. + Sets the selected parameters of the object's physics behavior.\nMaterialBits is a bitmask specifying which of the parameters in the other arguments should be applied to the object. GravityMultiplier, Restitution, Friction, and Density are the possible parameters to manipulate. llSetPos - energy - 10.0 - sleep - 0.2 - return - void arguments Position - type - vector tooltip Region coordinates to move to (within 10m). + type + vector - tooltip - If the object is not physical, this function sets the position of the prim.\nIf the script is in a child prim, Position is treated as root relative and the link-set is adjusted.\nIf the prim is the root prim, the entire object is moved (up to 10m) to Position in region coordinates. - - llSetPrimitiveParams - energy - 10.0 - sleep - 0.2 + 10 return void - arguments - - - Parameters - - type - list - tooltip - A list of changes. - - - + sleep + 0.2000000000000000111022302 tooltip - This function changes the many properties (or "parameters") of a prim in one operation. Parameters is a list of changes. + If the object is not physical, this function sets the position of the prim.\nIf the script is in a child prim, Position is treated as root relative and the link-set is adjusted.\nIf the prim is the root prim, the entire object is moved (up to 10m) to Position in region coordinates. llSetPrimMediaParams - energy - 10.0 - sleep - 1.0 - return - integer arguments Face - type - integer tooltip Face number + type + integer MediaParameters - type - list tooltip A set of name/value pairs (in no particular order) + type + list + energy + 10 + return + integer + sleep + 1 tooltip Sets the MediaParameters for a particular Face on the prim. Returns an integer that is a STATUS_* flag which details the success/failure of the operation(s).\nMediaParameters is a set of name/value pairs in no particular order. Parameters not specified are unchanged, or if new media is added then set to the default specified. llSetPrimURL - deprecated - true - energy - 10.0 - sleep - 20.0 - return - void arguments URL + tooltip + type string - tooltip - + deprecated + 1 + energy + 10 + return + void + sleep + 20 tooltip Deprecated: Use llSetPrimMediaParams instead. - llSetRegionPos + llSetPrimitiveParams + arguments + + + Parameters + + tooltip + A list of changes. + type + list + + + energy - 0.0 - sleep - 0.0 + 10 return - integer + void + sleep + 0.2000000000000000111022302 + tooltip + This function changes the many properties (or "parameters") of a prim in one operation. Parameters is a list of changes. + + llSetRegionPos + arguments Position - type - vector tooltip Vector. The location to move to, in region coordinates. + type + vector + energy + 10 + return + integer + sleep + 0 tooltip Attempts to move the object so that the root prim is within 0.1m of Position.\nReturns an integer boolean, TRUE if the object is successfully placed within 0.1 m of Position, FALSE otherwise.\nPosition may be any location within the region or up to 10m across a region border.\nIf the position is below ground, it will be set to the ground level at that x,y location. llSetRemoteScriptAccessPin - energy - 10.0 - sleep - 0.2 - return - void arguments PIN + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0.2000000000000000111022302 tooltip If PIN is set to a non-zero number, the task will accept remote script loads via llRemoteLoadScriptPin() if it passes in the correct PIN. Othersise, llRemoteLoadScriptPin() is ignored. - llSetRot + llSetRenderMaterial + arguments + + + Material + + tooltip + + type + string + + + + Face + + tooltip + + type + integer + + + energy - 10.0 - sleep - 0.2 + 10 return void + sleep + 0.2000000000000000111022302 + tooltip + Applies Render Material to Face of prim.\nRender Material may be a UUID or name of a material in prim inventory.\nIf Face is ALL_SIDES, set the render material on all faces. + + llSetRot + arguments Rotation + tooltip + type rotation - tooltip - + energy + 10 + return + void + sleep + 0.2000000000000000111022302 tooltip If the object is not physical, this function sets the rotation of the prim.\nIf the script is in a child prim, Rotation is treated as root relative and the link-set is adjusted.\nIf the prim is the root prim, the entire object is rotated to Rotation in the global reference frame. llSetScale - energy - 10.0 - sleep - 0.0 - return - void arguments Scale + tooltip + type vector - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Sets the prim's scale (size) to Scale. + Sets the prim's scale (size) to Scale. llSetScriptState - energy - 10.0 - sleep - 0.0 - return - void arguments ScriptName + tooltip + type string - tooltip - Running + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Enable or disable the script Running state of Script in the prim. llSetSitText - energy - 10.0 - sleep - 0.0 - return - void arguments Text + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - Displays Text rather than 'Sit' in the viewer's context menu. + Displays Text rather than 'Sit' in the viewer's context menu. llSetSoundQueueing - energy - 10.0 - sleep - 0.0 - return - void arguments QueueEnable - type - integer tooltip Boolean, sound queuing: TRUE enables, FALSE disables (default). + type + integer + energy + 10 + return + void + sleep + 0 tooltip Sets whether successive calls to llPlaySound, llLoopSound, etc., (attached sounds) interrupt the currently playing sound.\nThe default for objects is FALSE. Setting this value to TRUE will make the sound wait until the current playing sound reaches its end. The queue is one level deep. llSetSoundRadius - energy - 10.0 - sleep - 0.0 - return - void arguments Radius - type - float tooltip Maximum distance that sounds can be heard. + type + float + energy + 10 + return + void + sleep + 0 tooltip Limits radius for audibility of scripted sounds (both attached and triggered) to distance Radius. llSetStatus - energy - 10.0 - sleep - 0.0 - return - void arguments Status + tooltip + type integer - tooltip - Value + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets object status specified in Status bitmask (e.g. STATUS_PHYSICS|STATUS_PHANTOM) to boolean Value.\nFor a full list of STATUS_* constants, see wiki documentation. llSetText - energy - 10.0 - sleep - 0.0 - return - void arguments Text + tooltip + type string - tooltip - Color + tooltip + type vector - tooltip - Opacity + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Causes Text to float above the prim, using the specified Color and Opacity. llSetTexture - energy - 10.0 - sleep - 0.2 - return - void arguments Texture + tooltip + type string - tooltip - Face + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0.2000000000000000111022302 tooltip Applies Texture to Face of prim.\nTexture may be a UUID or name of a texture in prim inventory.\nIf Face is ALL_SIDES, set the texture on all faces. llSetTextureAnim - energy - 10.0 - sleep - 0.0 - return - void arguments Mode - type - integer tooltip Mask of Mode flags. + type + integer Face - type - integer tooltip Face number or ALL_SIDES. + type + integer SizeX - type - integer tooltip Horizontal frames (ignored for ROTATE and SCALE). + type + integer SizeY - type - integer tooltip Vertical frames (ignored for ROTATE and SCALE). + type + integer Start - type - float tooltip Start position/frame number (or radians for ROTATE). + type + float Length - type - float tooltip number of frames to display (or radians for ROTATE). + type + float Rate - type - float tooltip Frames per second (must not greater than zero). + type + float + energy + 10 + return + void + sleep + 0 tooltip Animates a texture by setting the texture scale and offset.\nMode is a bitmask of animation options.\nFace specifies which object face to animate.\nSizeX and SizeY specify the number of horizontal and vertical frames.Start specifes the animation start point.\nLength specifies the animation duration.\nRate specifies the animation playback rate. llSetTimerEvent - energy - 10.0 - sleep - 0.0 - return - void arguments Rate + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Causes the timer event to be triggered every Rate seconds.\n Passing in 0.0 stops further timer events. llSetTorque - energy - 10.0 - sleep - 0.0 - return - void arguments Torque - type - vector tooltip Torque force. + type + vector Local - type - integer tooltip Boolean, if TRUE uses local axis, if FALSE uses region axis. + type + integer + energy + 10 + return + void + sleep + 0 tooltip - Sets the Torque acting on the script's object, in object-local coordinates if Local == TRUE (otherwise, the region reference frame is used).\nOnly works on physical objects. + Sets the Torque acting on the script's object, in object-local coordinates if Local == TRUE (otherwise, the region reference frame is used).\nOnly works on physical objects. llSetTouchText - energy - 10.0 - sleep - 0.0 - return - void arguments Text + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Displays Text in the viewer context menu that acts on a touch. llSetVehicleFlags - energy - 10.0 - sleep - 0.0 - return - void arguments Flags + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Enables the vehicle flags specified in the Flags bitmask.\nValid parameters can be found in the wiki documentation. llSetVehicleFloatParam - energy - 10.0 - sleep - 0.0 - return - void arguments ParameterName + tooltip + type integer - tooltip - ParameterValue + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets a vehicle float parameter.\nValid parameters can be found in the wiki documentation. llSetVehicleRotationParam - energy - 10.0 - sleep - 0.0 - return - void arguments ParameterName + tooltip + type integer - tooltip - ParameterValue + tooltip + type rotation - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets a vehicle rotation parameter.\nValid parameters can be found in the wiki documentation. llSetVehicleType - energy - 10.0 - sleep - 0.0 - return - void arguments Type + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Activates the vehicle action on the object with vehicle preset Type.\nValid Types and an explanation of their characteristics can be found in wiki documentation. llSetVehicleVectorParam - energy - 10.0 - sleep - 0.0 - return - void arguments ParameterName + tooltip + type integer - tooltip - ParameterValue + tooltip + type vector - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Sets a vehicle vector parameter.\nValid parameters can be found in the wiki documentation. llSetVelocity - energy - - sleep - 0.0 - return - void arguments Velocity - type - vector tooltip The velocity to apply. + type + vector Local - type - integer tooltip If TRUE, the Velocity is treated as a local directional vector instead of a regional directional vector. + type + integer + energy + 10 + return + void + sleep + 0 tooltip - If the object is physics-enabled, sets the object's linear velocity to Velocity.\nIf Local==TRUE, Velocity is treated as a local directional vector; otherwise, Velocity is treated as a global directional vector. + If the object is physics-enabled, sets the object's linear velocity to Velocity.\nIf Local==TRUE, Velocity is treated as a local directional vector; otherwise, Velocity is treated as a global directional vector. - llSHA1String + llShout - energy - 10.0 - sleep - 0.0 - return - string arguments + + Channel + + tooltip + + type + integer + + Text + tooltip + type string - tooltip - - tooltip - Returns a string of 40 hex characters that is the SHA1 security Hash of Text. - - llShout - energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + Shouts Text on Channel.\nThis chat method has a range of 100m radius.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. + + llSignRSA + arguments - Channel + PrivateKey - type - integer tooltip - + The PEM-formatted private key + type + string - Text + Message + tooltip + The message contents to sign type string + + + + Algorithm + tooltip - + The digest algorithnm to use: sha1, sha224, sha256, sha384, sha512 + type + string + energy + 10 + return + string + sleep + 0 tooltip - Shouts Text on Channel.\nThis chat method has a range of 100m radius.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. + Returns the base64-encoded RSA signature of Message using PEM-formatted PrivateKey and digest Algorithm (sha1, sha224, sha256, sha384, sha512). llSin - energy - 10.0 - sleep - 0.0 - return - float arguments Theta + tooltip + type float - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Returns the sine of Theta (Theta in radians). - llSitTarget + llSitOnLink + arguments + + + AvatarID + + tooltip + + type + key + + + + LinkID + + tooltip + + type + integer + + + energy - 10.0 - sleep - 0.0 + 10 return - void + integer + sleep + 0 + tooltip + If agent identified by AvatarID is participating in the experience, sit them on the specified link's sit target. + + llSitTarget + arguments Offset + tooltip + type vector - tooltip - Rotation + tooltip + type rotation - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Set the sit location for this object. If offset == ZERO_VECTOR, clears the sit target. llSleep - energy - 0 - sleep - 0.0 - return - void arguments Time + tooltip + type float - tooltip - + energy + 0 + return + void + sleep + 0 tooltip Put script to sleep for Time seconds. llSound - deprecated - true - energy - 10.0 - sleep - 0.0 - return - void arguments Sound + tooltip + type string - tooltip - Volume + tooltip + type float - tooltip - Queue + tooltip + type integer - tooltip - Loop + tooltip + type integer - tooltip - + deprecated + 1 + energy + 10 + return + void + sleep + 0 tooltip Deprecated: Use llPlaySound instead.\nPlays Sound at Volume and specifies whether the sound should loop and/or be enqueued. llSoundPreload - deprecated - true - energy - 10.0 - sleep - 0.0 - return - void arguments Sound + tooltip + type string - tooltip - + deprecated + 1 + energy + 10 + return + void + sleep + 0 tooltip Deprecated: Use llPreloadSound instead.\nPreloads a sound on viewers within range. llSqrt - energy - 10.0 - sleep - 0.0 - return - float arguments Value + tooltip + type float - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Returns the square root of Value.\nTriggers a math runtime error for imaginary results (if Value < 0.0). llStartAnimation + arguments + + + Animation + + tooltip + + type + string + + + energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + This function plays the specified animation from playing on the avatar who received the script's most recent permissions request.\nAnimation may be an animation in task inventory or a built-in animation.\nRequires PERMISSION_TRIGGER_ANIMATION. + + llStartObjectAnimation + arguments Animation + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - This function plays the specified animation from playing on the avatar who received the script's most recent permissions request.\nAnimation may be an animation in task inventory or a built-in animation.\nRequires PERMISSION_TRIGGER_ANIMATION. + This function plays the specified animation on the rigged mesh object associated with the current script.\nAnimation may be an animation in task inventory or a built-in animation.\n llStopAnimation - energy - 10.0 - sleep - 0.0 - return - void arguments Animation + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip - This function stops the specified animation on the avatar who received the script's most recent permissions request.\nAnimation may be an animation in task inventory, a built-in animation, or the uuid of an animation.\nRequires PERMISSION_TRIGGER_ANIMATION. + This function stops the specified animation on the avatar who received the script's most recent permissions request.\nAnimation may be an animation in task inventory, a built-in animation, or the uuid of an animation.\nRequires PERMISSION_TRIGGER_ANIMATION. llStopHover + arguments + energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0 tooltip Stop hovering to a height (due to llSetHoverHeight()). llStopLookAt + arguments + energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0 tooltip Stop causing object to point at a target (due to llLookAt() or llRotLookAt()). llStopMoveToTarget + arguments + energy - 10.0 - sleep - 0.0 + 10 return void - arguments - + sleep + 0 tooltip Stops critically damped motion (due to llMoveToTarget()). - llStopSound + llStopObjectAnimation + arguments + + + Animation + + tooltip + + type + string + + + energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + This function stops the specified animation on the rigged mesh object associated with the current script.\nAnimation may be an animation in task inventory, a built-in animation, or the uuid of an animation.\n + + llStopSound + arguments - + + energy + 10 + return + void + sleep + 0 tooltip Stops playback of the currently attached sound. llStringLength - energy - 10.0 - sleep - 0.0 - return - integer arguments Text + tooltip + type string - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip Returns an integer that is the number of characters in Text (not counting the null). llStringToBase64 - energy - 10.0 - sleep - 0.0 - return - string arguments Text + tooltip + type string - tooltip - + energy + 10 + return + string + sleep + 0 tooltip Returns the string Base64 representation of the input string. llStringTrim - energy - 10.0 - sleep - 0.0 - return - string arguments Text - type - string tooltip String to trim + type + string TrimType - type - integer tooltip STRING_TRIM_HEAD, STRING_TRIM_TAIL, or STRING_TRIM. + type + integer + energy + 10 + return + string + sleep + 0 tooltip Outputs a string, eliminating white-space from the start and/or end of the input string Text.\nValid options for TrimType:\nSTRING_TRIM_HEAD: trim all leading spaces in Text\nSTRING_TRIM_TAIL: trim all trailing spaces in Text\nSTRING_TRIM: trim all leading and trailing spaces in Text. llSubStringIndex - energy - 10.0 - sleep - 0.0 - return - integer arguments Text + tooltip + type string - tooltip - Sequence + tooltip + type string - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip Returns an integer that is the index in Text where string pattern Sequence first appears. Returns -1 if not found. llTakeCamera - deprecated - true - energy - 10.0 - sleep - 0.0 - return - void arguments AvatarID + tooltip + type key - tooltip - + deprecated + 1 + energy + 10 + return + void + sleep + 0 tooltip Deprecated: Use llSetCameraParams instead. llTakeControls - energy - 10.0 - sleep - 0.0 - return - void arguments Controls - type - integer tooltip Bit-field of CONTROL_* flags. + type + integer Accept - type - integer tooltip Boolean, determines whether control events are generated. + type + integer PassOn - type - integer tooltip Boolean, determines whether controls are disabled. + type + integer + energy + 10 + return + void + sleep + 0 tooltip Take controls from the agent the script has permissions for.\nIf (Accept == (Controls & input)), send input to the script. PassOn determines whether Controls also perform their normal functions.\nRequires the PERMISSION_TAKE_CONTROLS permission to run. llTan - energy - 10.0 - sleep - 0.0 - return - float arguments Theta + tooltip + type float - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Returns the tangent of Theta (Theta in radians). llTarget - energy - 10.0 - sleep - 0.0 - return - integer arguments Position + tooltip + type vector - tooltip - Range + tooltip + type float - tooltip - + energy + 10 + return + integer + sleep + 0 tooltip This function is to have the script know when it has reached a position.\nIt registers a Position with a Range that triggers at_target and not_at_target events continuously until unregistered. llTargetOmega - energy - 10.0 - sleep - 0.0 - return - void arguments Axis + tooltip + type vector - tooltip - SpinRate + tooltip + type float - tooltip - Gain + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Attempt to spin at SpinRate with strength Gain on Axis.\nA spin rate of 0.0 cancels the spin. This function always works in object-local coordinates. llTargetRemove + arguments + + + Target + + tooltip + + type + integer + + + energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + Removes positional target Handle registered with llTarget. + + llTargetedEmail + arguments Target + tooltip + + type + integer + + + + Subject + + tooltip + type - integer + string + + + + Text + tooltip - + + type + string + energy + 10 + return + void + sleep + 20 tooltip - Removes positional target Handle registered with llTarget. + Sends an email with Subject and Message to the owner or creator of an object . llTeleportAgent - energy - 0 - sleep - 0 - return - void arguments AvatarID - type - key tooltip UUID of avatar. + type + key LandmarkName - type - string tooltip Name of landmark (in object contents), or empty string, to use. + type + string Position - type - vector tooltip If no landmark was provided, the position within the current region to teleport the avatar to. + type + vector LookAtPoint - type - vector tooltip The position within the target region that the avatar should be turned to face upon arrival. + type + vector + energy + 10 + return + void + sleep + 0 tooltip - Requests a teleport of avatar to a landmark stored in the object's inventory. If no landmark is provided (an empty string), the avatar is teleported to the location position in the current region. In either case, the avatar is turned to face the position given by look_at in local coordinates.\nRequires the PERMISSION_TELEPORT permission. This function can only teleport the owner of the object. + Requests a teleport of avatar to a landmark stored in the object's inventory. If no landmark is provided (an empty string), the avatar is teleported to the location position in the current region. In either case, the avatar is turned to face the position given by look_at in local coordinates.\nRequires the PERMISSION_TELEPORT permission. This function can only teleport the owner of the object. llTeleportAgentGlobalCoords - energy - 0 - sleep - 0 - return - void arguments AvatarID - type - key tooltip UUID of avatar. + type + key GlobalPosition - type - vector tooltip Global coordinates of the destination region. Can be retrieved by using llRequestSimulatorData(region_name, DATA_SIM_POS). + type + vector RegionPosition - type - vector tooltip The position within the target region to teleport the avatar to, if no landmark was provided. + type + vector LookAtPoint - type - vector tooltip The position within the target region that the avatar should be turned to face upon arrival. + type + vector + energy + 10 + return + void + sleep + 0 tooltip Teleports an agent to the RegionPosition local coordinates within a region which is specified by the GlobalPosition global coordinates. The agent lands facing the position defined by LookAtPoint local coordinates.\nRequires the PERMISSION_TELEPORT permission. This function can only teleport the owner of the object. llTeleportAgentHome - energy - 100.0 - sleep - 5.0 - return - void arguments AvatarID + tooltip + type key - tooltip - + energy + 100 + return + void + sleep + 5 tooltip - Teleport agent over the owner's land to agent's home location. + Teleport agent over the owner's land to agent's home location. llTextBox - energy - 10.0 - sleep - 1.0 - return - void arguments AvatarID + tooltip + type key - tooltip - Text + tooltip + type string - tooltip - Channel + tooltip + type integer - tooltip - + energy + 10 + return + void + sleep + 1 tooltip - Opens a dialog for the specified avatar with message Text, which contains a text box for input. Any text that is entered is said on the specified Channel (as if by the avatar) when the "OK" button is clicked. + Opens a dialog for the specified avatar with message Text, which contains a text box for input. Any text that is entered is said on the specified Channel (as if by the avatar) when the "OK" button is clicked. llToLower - energy - 10.0 - sleep - 0.0 - return - string arguments Text + tooltip + type string - tooltip - + energy + 10 + return + string + sleep + 0 tooltip Returns a string that is Text with all lower-case characters. llToUpper - energy - 10.0 - sleep - 0.0 - return - string arguments Text + tooltip + type string - tooltip - + energy + 10 + return + string + sleep + 0 tooltip Returns a string that is Text with all upper-case characters. llTransferLindenDollars - energy - 10.0 - sleep - 0.0 - return - key arguments AvatarID + tooltip + type key - tooltip - Amount + tooltip + type integer - tooltip - + energy + 10 + return + key + sleep + 0 tooltip Transfer Amount of linden dollars (L$) from script owner to AvatarID. Returns a key to a corresponding transaction_result event for the success of the transfer.\nAttempts to send the amount of money to the specified avatar, and trigger a transaction_result event identified by the returned key. - llTriggerSound + llTransferOwnership + arguments + + + AgentID + + tooltip + An agent in the region. + type + key + + + + Flags + + tooltip + Flags to control type of inventory transfer. + type + integer + + + + Params + + tooltip + Extra parameters to llTransferOwnership. None are defined at this time. + type + list + + + energy - 10.0 - sleep - 0.0 + 10 return - void + integer + sleep + 0 + tooltip + Transfers ownership of an object, or a copy of the object to a new agent. + + llTriggerSound + arguments Sound + tooltip + type string - tooltip - Volume + tooltip + type float - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Plays Sound at Volume (0.0 - 1.0), centered at but not attached to object.\nThere is no limit to the number of triggered sounds which can be generated by an object, and calling llTriggerSound does not affect the attached sounds created by llPlaySound and llLoopSound. This is very useful for things like collision noises, explosions, etc. There is no way to stop or alter the volume of a sound triggered by this function. llTriggerSoundLimited - energy - 10.0 - sleep - 0.0 - return - void arguments Sound + tooltip + type string - tooltip - Volume + tooltip + type float - tooltip - TNE + tooltip + type vector - tooltip - BSW + tooltip + type vector - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Plays Sound at Volume (0.0 - 1.0), centered at but not attached to object, limited to axis-aligned bounding box defined by vectors top-north-east (TNE) and bottom-south-west (BSW).\nThere is no limit to the number of triggered sounds which can be generated by an object, and calling llTriggerSound does not affect the attached sounds created by llPlaySound and llLoopSound. This is very useful for things like collision noises, explosions, etc. There is no way to stop or alter the volume of a sound triggered by this function. - llUnescapeURL + llUnSit - energy - 10.0 - sleep - 0.0 - return - string arguments - URL + AvatarID - type - string tooltip - + + type + key - tooltip - Returns the string that is the URL unescaped, replacing "%20" with spaces, etc., version of URL.\nThis function can output raw UTF-8 strings. - - llUnSit - energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + If agent identified by AvatarID is sitting on the object the script is attached to or is over land owned by the objects owner, the agent is forced to stand up. + + llUnescapeURL + arguments - AvatarID + URL - type - key tooltip - + + type + string + energy + 10 + return + string + sleep + 0 tooltip - If agent identified by AvatarID is sitting on the object the script is attached to or is over land owned by the objects owner, the agent is forced to stand up. + Returns the string that is the URL unescaped, replacing "%20" with spaces, etc., version of URL.\nThis function can output raw UTF-8 strings. llUpdateCharacter + arguments + + + Options + + tooltip + Character configuration options. Takes the same constants as llCreateCharacter(). + type + list + + + energy - 10.0 - sleep - 0.0 + 10 return void + sleep + 0 + tooltip + Updates settings for a pathfinding character. + + llUpdateKeyValue + arguments - Options + Key + + tooltip + + type + string + + + + Value + + tooltip + + type + string + + + + Checked + tooltip + type - list + integer + + + + OriginalValue + tooltip - Character configuration options. Takes the same constants as llCreateCharacter(). + + type + string - tooltip - Updates settings for a pathfinding character. - - llUpdateKeyValue - energy - 10.0 - sleep - 0.0 + 10 return key - arguments - - - Key - - type - string - tooltip - - - - - Value - - type - string - tooltip - - - - - Checked - - type - integer - tooltip - - - - - OriginalValue - - type - string - tooltip - - - - + sleep + 0 tooltip Starts an asychronous transaction to update the value associated with the key given. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. If Checked is 1 the existing value in the data store must match the OriginalValue passed or XP_ERROR_RETRY_UPDATE will be returned. If Checked is 0 the key will be created if necessary. @@ -18810,349 +23974,419 @@ llVecDist - energy - 10.0 - sleep - 0.0 - return - float arguments Location1 + tooltip + type vector - tooltip - Location2 + tooltip + type vector - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Returns the distance between Location1 and Location2. llVecMag - energy - 10.0 - sleep - 0.0 - return - float arguments Vector + tooltip + type vector - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Returns the magnitude of the vector. llVecNorm - energy - 10.0 - sleep - 0.0 - return - vector arguments Vector + tooltip + type vector - tooltip - + energy + 10 + return + vector + sleep + 0 tooltip Returns normalized vector. - llVolumeDetect + llVerifyRSA + arguments + + + PublicKey + + tooltip + The PEM-formatted public key for signature verifiation. + type + string + + + + Message + + tooltip + The message that was signed. + type + string + + + + Signature + + tooltip + The base64-formatted signature of the message. + type + string + + + + Algorithm + + tooltip + The digest algorithm: sha1, sha224, sha256, sha384, sha512. + type + string + + + energy - 10.0 - sleep - 0.0 + 10 return - void + integer + sleep + 0 + tooltip + Returns TRUE if PublicKey, Message, and Algorithm produce the same base64-formatted Signature. + + llVolumeDetect + arguments DetectEnabled - type - integer tooltip TRUE enables, FALSE disables. + type + integer + energy + 10 + return + void + sleep + 0 tooltip If DetectEnabled = TRUE, object becomes phantom but triggers collision_start and collision_end events when other objects start and stop interpenetrating.\nIf another object (including avatars) interpenetrates it, it will get a collision_start event.\nWhen an object stops interpenetrating, a collision_end event is generated. While the other is inter-penetrating, collision events are NOT generated. llWanderWithin - energy - 10.0 - sleep - 0.0 - return - void arguments Origin - type - vector tooltip Central point to wander about. + type + vector Area - type - vector tooltip Half-extents of an area the character may wander within. (i.e., it can wander from the specified origin by up to +/-Distance.x in x, +/-Distance.y in y, etc.) + type + vector Options - type - list tooltip No options available at this time. + type + list + energy + 10 + return + void + sleep + 0 tooltip Wander within a specified volume.\nSets a character to wander about a central spot within a specified area. llWater - energy - 10.0 - sleep - 0.0 - return - float arguments Offset + tooltip + type vector - tooltip - + energy + 10 + return + float + sleep + 0 tooltip Returns the water height below the object position + Offset. llWhisper - energy - 10.0 - sleep - 0.0 - return - void arguments Channel + tooltip + type integer - tooltip - Text + tooltip + type string - tooltip - + energy + 10 + return + void + sleep + 0 tooltip Whispers Text on Channel.\nThis chat method has a range of 10m radius.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. llWind - energy - 10.0 - sleep - 0.0 - return - vector arguments Offset + tooltip + type vector - tooltip - + energy + 10 + return + vector + sleep + 0 tooltip Returns the wind velocity at the object position + Offset. - llXorBase64 + llWorldPosToHUD + arguments + + + world_pos + + tooltip + The world-frame position to project into HUD space + type + vector + + + energy - 10.0 - sleep - 0.0 + 10 return - string + vector + sleep + 0 + tooltip + Returns the local position that would put the origin of a HUD object directly over world_pos as viewed by the current camera. + + llXorBase64 + arguments Text1 + tooltip + type string - tooltip - Text2 + tooltip + type string - tooltip - + energy + 10 + return + string + sleep + 0 tooltip Performs an exclusive OR on two Base64 strings and returns a Base64 string. Text2 repeats if it is shorter than Text1. llXorBase64Strings - deprecated - true - energy - 10.0 - sleep - 0.3 - return - string arguments Text1 + tooltip + type string - tooltip - Text2 + tooltip + type string - tooltip - + deprecated + 1 + energy + 10 + return + string + sleep + 0.2999999999999999888977698 tooltip Deprecated: Please use llXorBase64 instead.\nIncorrectly performs an exclusive OR on two Base64 strings and returns a Base64 string. Text2 repeats if it is shorter than Text1.\nRetained for backwards compatibility. llXorBase64StringsCorrect - deprecated - true - energy - 10.0 - sleep - 0.0 - return - string arguments Text1 + tooltip + type string - tooltip - Text2 + tooltip + type string - tooltip - - tooltip - Deprecated: Please use llXorBase64 instead.\nCorrectly (unless nulls are present) performs an exclusive OR on two Base64 strings and returns a Base64 string.\nText2 repeats if it is shorter than Text1. - - llGetMinScaleFactor - + deprecated + 1 energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - + string + sleep + 0 tooltip - Returns the smallest multiplicative uniform scale factor that can be successfully applied (via llScaleByFactor()) to the object without violating prim size or linkability rules. + Deprecated: Please use llXorBase64 instead.\nCorrectly (unless nulls are present) performs an exclusive OR on two Base64 strings and returns a Base64 string.\nText2 repeats if it is shorter than Text1. - llGetMaxScaleFactor + llsRGB2Linear + arguments + + + srgb + + tooltip + A color in the sRGB colorspace. + type + vector + + + energy - 10.0 - sleep - 0.0 + 10 return - float - arguments - + vector + sleep + 0 tooltip - Returns the largest multiplicative uniform scale factor that can be successfully applied (via llScaleByFactor()) to the object without violating prim size or linkability rules. + Converts a color from the sRGB to the linear colorspace. llsd-lsl-syntax-version diff --git a/indra/newview/app_settings/keywords_lua_default.xml b/indra/newview/app_settings/keywords_lua_default.xml new file mode 100644 index 00000000000..97e5a1d3558 --- /dev/null +++ b/indra/newview/app_settings/keywords_lua_default.xml @@ -0,0 +1,29294 @@ + + + + controls + + do + + tooltip + Lua do block: do ... end + + if + + tooltip + Lua if statement: if condition then ... end + + then + + tooltip + Lua then keyword: introduces the block executed when an if condition is true. + + else + + tooltip + Lua else keyword: specifies the alternative block in an if/else statement. + + elseif + + tooltip + Lua elseif keyword: provides an additional conditional branch in an if statement. + + end + + tooltip + Lua end keyword: closes control structures like if, do, while, for, and function. + + for + + tooltip + Lua for loop: for var = start, end, step do ... end + + goto + + tooltip + Lua goto statement: jumps to a specified label. + + return + + tooltip + Lua return statement: returns a value from a function. + + while + + tooltip + Lua while loop: while condition do ... end + + repeat + + tooltip + Lua repeat loop: repeat ... until condition + + until + + tooltip + Lua until keyword: ends a repeat loop by testing a condition. + + function + + tooltip + Lua function keyword: begins a function definition. + + break + + tooltip + Lua break statement: exits the nearest loop. + + local + + tooltip + Lua local keyword: declares a local variable or function. + + in + + tooltip + Lua in keyword: used in generic for loops to iterate over elements. + + not + + tooltip + Lua not operator: performs logical negation. + + and + + tooltip + Lua and operator: performs logical conjunction. + + or + + tooltip + Lua or operator: performs logical disjunction. + + + types + + boolean + + tooltip + Boolean: represents a true or false value. + + number + + tooltip + Double‑precision floating point number. + + string + + tooltip + Text data (UTF‑8). + + table + + tooltip + Collection of key‑value pairs. + + thread + + tooltip + Represents a coroutine. + + userdata + + tooltip + Opaque external data. + + vector + + tooltip + A vector is a data type that contains a set of three float values.\nVectors are used to represent colors (RGB), positions, and directions/velocities. + + uuid + + tooltip + A 128‑bit unique identifier formatted as 36 hexadecimal characters (8‑4‑4‑4‑12), e.g. "A822FF2B-FF02-461D-B45D-DCD10A2DE0C2". + + + constants + + + nil + + tooltip + Lua nil: represents the absence of a useful value. + + true + + tooltip + Lua true: Boolean true value. + + false + + tooltip + Lua false: Boolean false value. + + + ACTIVE + + tooltip + Objects in world that are running a script or currently physically moving. + type + integer + value + 0x2 + + AGENT + + tooltip + Objects in world that are agents. + type + integer + value + 0x1 + + AGENT_ALWAYS_RUN + + tooltip + + type + integer + value + 0x1000 + + AGENT_ATTACHMENTS + + tooltip + The agent has attachments. + type + integer + value + 0x2 + + AGENT_AUTOMATED + + tooltip + The agent has been identified as a scripted agent + type + integer + value + 0x4000 + + AGENT_AUTOPILOT + + tooltip + + type + integer + value + 0x2000 + + AGENT_AWAY + + tooltip + + type + integer + value + 0x40 + + AGENT_BUSY + + tooltip + + type + integer + value + 0x800 + + AGENT_BY_LEGACY_NAME + + tooltip + + type + integer + value + 0x1 + + AGENT_BY_USERNAME + + tooltip + + type + integer + value + 0x10 + + AGENT_CROUCHING + + tooltip + + type + integer + value + 0x400 + + AGENT_FLOATING_VIA_SCRIPTED_ATTACHMENT + + tooltip + The agent is floating via scripted attachment. + type + integer + value + 0x8000 + + AGENT_FLYING + + tooltip + The agent is flying. + type + integer + value + 0x1 + + AGENT_IN_AIR + + tooltip + + type + integer + value + 0x100 + + AGENT_LIST_PARCEL + + tooltip + Agents on the same parcel where the script is running. + type + integer + value + 1 + + AGENT_LIST_PARCEL_OWNER + + tooltip + Agents on any parcel in the region where the parcel owner is the same as the owner of the parcel under the scripted object. + type + integer + value + 2 + + AGENT_LIST_REGION + + tooltip + All agents in the region. + type + integer + value + 4 + + AGENT_MOUSELOOK + + tooltip + + type + integer + value + 0x8 + + AGENT_ON_OBJECT + + tooltip + + type + integer + value + 0x20 + + AGENT_SCRIPTED + + tooltip + The agent has scripted attachments. + type + integer + value + 0x4 + + AGENT_SITTING + + tooltip + + type + integer + value + 0x10 + + AGENT_TYPING + + tooltip + + type + integer + value + 0x200 + + AGENT_WALKING + + tooltip + + type + integer + value + 0x80 + + ALL_SIDES + + tooltip + + type + integer + value + -1 + + ANIM_ON + + tooltip + Texture animation is on. + type + integer + value + 0x1 + + ATTACH_ANY_HUD + + tooltip + Filtering for any HUD attachment. + type + integer + value + -1 + + ATTACH_AVATAR_CENTER + + tooltip + Attach to the avatar's geometric centre. + type + integer + value + 40 + + ATTACH_BACK + + tooltip + Attach to the avatar's back. + type + integer + value + 9 + + ATTACH_BELLY + + tooltip + Attach to the avatar's belly. + type + integer + value + 28 + + ATTACH_CHEST + + tooltip + Attach to the avatar's chest. + type + integer + value + 1 + + ATTACH_CHIN + + tooltip + Attach to the avatar's chin. + type + integer + value + 12 + + ATTACH_FACE_JAW + + tooltip + Attach to the avatar's jaw. + type + integer + value + 47 + + ATTACH_FACE_LEAR + + tooltip + Attach to the avatar's left ear (extended). + type + integer + value + 48 + + ATTACH_FACE_LEYE + + tooltip + Attach to the avatar's left eye (extended). + type + integer + value + 50 + + ATTACH_FACE_REAR + + tooltip + Attach to the avatar's right ear (extended). + type + integer + value + 49 + + ATTACH_FACE_REYE + + tooltip + Attach to the avatar's right eye (extended). + type + integer + value + 51 + + ATTACH_FACE_TONGUE + + tooltip + Attach to the avatar's tongue. + type + integer + value + 52 + + ATTACH_GROIN + + tooltip + Attach to the avatar's groin. + type + integer + value + 53 + + ATTACH_HEAD + + tooltip + Attach to the avatar's head. + type + integer + value + 2 + + ATTACH_HIND_LFOOT + + tooltip + Attach to the avatar's left hind foot. + type + integer + value + 54 + + ATTACH_HIND_RFOOT + + tooltip + Attach to the avatar's right hind foot. + type + integer + value + 55 + + ATTACH_HUD_BOTTOM + + tooltip + + type + integer + value + 37 + + ATTACH_HUD_BOTTOM_LEFT + + tooltip + + type + integer + value + 36 + + ATTACH_HUD_BOTTOM_RIGHT + + tooltip + + type + integer + value + 38 + + ATTACH_HUD_CENTER_1 + + tooltip + + type + integer + value + 35 + + ATTACH_HUD_CENTER_2 + + tooltip + + type + integer + value + 31 + + ATTACH_HUD_TOP_CENTER + + tooltip + + type + integer + value + 33 + + ATTACH_HUD_TOP_LEFT + + tooltip + + type + integer + value + 34 + + ATTACH_HUD_TOP_RIGHT + + tooltip + + type + integer + value + 32 + + ATTACH_LEAR + + tooltip + Attach to the avatar's left ear. + type + integer + value + 13 + + ATTACH_LEFT_PEC + + tooltip + Attach to the avatar's left pectoral. + type + integer + value + 29 + + ATTACH_LEYE + + tooltip + Attach to the avatar's left eye. + type + integer + value + 15 + + ATTACH_LFOOT + + tooltip + Attach to the avatar's left foot. + type + integer + value + 7 + + ATTACH_LHAND + + tooltip + Attach to the avatar's left hand. + type + integer + value + 5 + + ATTACH_LHAND_RING1 + + tooltip + Attach to the avatar's left ring finger. + type + integer + value + 41 + + ATTACH_LHIP + + tooltip + Attach to the avatar's left hip. + type + integer + value + 25 + + ATTACH_LLARM + + tooltip + Attach to the avatar's left lower arm. + type + integer + value + 21 + + ATTACH_LLLEG + + tooltip + Attach to the avatar's lower left leg. + type + integer + value + 27 + + ATTACH_LPEC + + deprecated + 1 + tooltip + Attach to the avatar's right pectoral. (Deprecated, use ATTACH_RIGHT_PEC) + type + integer + value + 30 + + ATTACH_LSHOULDER + + tooltip + Attach to the avatar's left shoulder. + type + integer + value + 3 + + ATTACH_LUARM + + tooltip + Attach to the avatar's left upper arm. + type + integer + value + 20 + + ATTACH_LULEG + + tooltip + Attach to the avatar's lower upper leg. + type + integer + value + 26 + + ATTACH_LWING + + tooltip + Attach to the avatar's left wing. + type + integer + value + 45 + + ATTACH_MOUTH + + tooltip + Attach to the avatar's mouth. + type + integer + value + 11 + + ATTACH_NECK + + tooltip + Attach to the avatar's neck. + type + integer + value + 39 + + ATTACH_NOSE + + tooltip + Attach to the avatar's nose. + type + integer + value + 17 + + ATTACH_PELVIS + + tooltip + Attach to the avatar's pelvis. + type + integer + value + 10 + + ATTACH_REAR + + tooltip + Attach to the avatar's right ear. + type + integer + value + 14 + + ATTACH_REYE + + tooltip + Attach to the avatar's right eye. + type + integer + value + 16 + + ATTACH_RFOOT + + tooltip + Attach to the avatar's right foot. + type + integer + value + 8 + + ATTACH_RHAND + + tooltip + Attach to the avatar's right hand. + type + integer + value + 6 + + ATTACH_RHAND_RING1 + + tooltip + Attach to the avatar's right ring finger. + type + integer + value + 42 + + ATTACH_RHIP + + tooltip + Attach to the avatar's right hip. + type + integer + value + 22 + + ATTACH_RIGHT_PEC + + tooltip + Attach to the avatar's right pectoral. + type + integer + value + 30 + + ATTACH_RLARM + + tooltip + Attach to the avatar's right lower arm. + type + integer + value + 19 + + ATTACH_RLLEG + + tooltip + Attach to the avatar's right lower leg. + type + integer + value + 24 + + ATTACH_RPEC + + deprecated + 1 + tooltip + Attach to the avatar's left pectoral. (deprecated, use ATTACH_LEFT_PEC) + type + integer + value + 29 + + ATTACH_RSHOULDER + + tooltip + Attach to the avatar's right shoulder. + type + integer + value + 4 + + ATTACH_RUARM + + tooltip + Attach to the avatar's right upper arm. + type + integer + value + 18 + + ATTACH_RULEG + + tooltip + Attach to the avatar's right upper leg. + type + integer + value + 23 + + ATTACH_RWING + + tooltip + Attach to the avatar's right wing. + type + integer + value + 46 + + ATTACH_TAIL_BASE + + tooltip + Attach to the avatar's tail base. + type + integer + value + 43 + + ATTACH_TAIL_TIP + + tooltip + Attach to the avatar's tail tip. + type + integer + value + 44 + + AVOID_CHARACTERS + + tooltip + + type + integer + value + 1 + + AVOID_DYNAMIC_OBSTACLES + + tooltip + + type + integer + value + 2 + + AVOID_NONE + + tooltip + + type + integer + value + 0 + + BEACON_MAP + + tooltip + Cause llMapBeacon to optionally display and focus the world map on the avatar's viewer. + type + integer + value + 1 + + CAMERA_ACTIVE + + tooltip + + type + integer + value + 12 + + CAMERA_BEHINDNESS_ANGLE + + tooltip + + type + integer + value + 8 + + CAMERA_BEHINDNESS_LAG + + tooltip + + type + integer + value + 9 + + CAMERA_DISTANCE + + tooltip + + type + integer + value + 7 + + CAMERA_FOCUS + + tooltip + + type + integer + value + 17 + + CAMERA_FOCUS_LAG + + tooltip + + type + integer + value + 6 + + CAMERA_FOCUS_LOCKED + + tooltip + + type + integer + value + 22 + + CAMERA_FOCUS_OFFSET + + tooltip + + type + integer + value + 1 + + CAMERA_FOCUS_THRESHOLD + + tooltip + + type + integer + value + 11 + + CAMERA_PITCH + + tooltip + + type + integer + value + 0 + + CAMERA_POSITION + + tooltip + + type + integer + value + 13 + + CAMERA_POSITION_LAG + + tooltip + + type + integer + value + 5 + + CAMERA_POSITION_LOCKED + + tooltip + + type + integer + value + 21 + + CAMERA_POSITION_THRESHOLD + + tooltip + + type + integer + value + 10 + + CHANGED_ALLOWED_DROP + + tooltip + The object inventory has changed because an item was added through the llAllowInventoryDrop interface. + type + integer + value + 0x40 + + CHANGED_COLOR + + tooltip + The object color has changed. + type + integer + value + 0x2 + + CHANGED_INVENTORY + + tooltip + The object inventory has changed. + type + integer + value + 0x1 + + CHANGED_LINK + + tooltip + The object has linked or its links were broken. + type + integer + value + 0x20 + + CHANGED_MEDIA + + tooltip + + type + integer + value + 0x800 + + CHANGED_OWNER + + tooltip + + type + integer + value + 0x80 + + CHANGED_REGION + + tooltip + + type + integer + value + 0x100 + + CHANGED_REGION_START + + tooltip + + type + integer + value + 0x400 + + CHANGED_RENDER_MATERIAL + + tooltip + The render material has changed. + type + integer + value + 0x1000 + + CHANGED_SCALE + + tooltip + The object scale (size) has changed. + type + integer + value + 0x8 + + CHANGED_SHAPE + + tooltip + The object base shape has changed, e.g., a box to a cylinder. + type + integer + value + 0x4 + + CHANGED_TELEPORT + + tooltip + + type + integer + value + 0x200 + + CHANGED_TEXTURE + + tooltip + The texture offset, scale rotation, or simply the object texture has changed. + type + integer + value + 0x10 + + CHARACTER_ACCOUNT_FOR_SKIPPED_FRAMES + + tooltip + If set to false, character will not attempt to catch up on lost time when pathfinding performance is low, potentially providing more reliable movement (albeit while potentially appearing to be more stuttery). Default is true to match pre-existing behavior. + type + integer + value + 14 + + CHARACTER_AVOIDANCE_MODE + + tooltip + Allows you to specify that a character should not try to avoid other characters, should not try to avoid dynamic obstacles (relatively fast moving objects and avatars), or both. + type + integer + value + 5 + + CHARACTER_CMD_JUMP + + tooltip + Makes the character jump. Requires an additional parameter, the height to jump, between 0.1m and 2.0m. This must be provided as the first element of the llExecCharacterCmd option list. + type + integer + value + 0x01 + + CHARACTER_CMD_SMOOTH_STOP + + tooltip + + type + integer + value + 2 + + CHARACTER_CMD_STOP + + tooltip + Stops any current pathfinding operation. + type + integer + value + 0x00 + + CHARACTER_DESIRED_SPEED + + tooltip + Speed of pursuit in meters per second. + type + integer + value + 1 + + CHARACTER_DESIRED_TURN_SPEED + + tooltip + The character's maximum speed while turning about the Z axis. - Note that this is only loosely enforced. + type + integer + value + 12 + + CHARACTER_LENGTH + + tooltip + Set collision capsule length - cannot be less than two times the radius. + type + integer + value + 3 + + CHARACTER_MAX_ACCEL + + tooltip + The character's maximum acceleration rate. + type + integer + value + 8 + + CHARACTER_MAX_DECEL + + tooltip + The character's maximum deceleration rate. + type + integer + value + 9 + + CHARACTER_MAX_SPEED + + tooltip + The character's maximum speed. + type + integer + value + 13 + + CHARACTER_MAX_TURN_RADIUS + + tooltip + The character's turn radius when travelling at CHARACTER_MAX_TURN_SPEED. + type + integer + value + 10 + + CHARACTER_ORIENTATION + + tooltip + Valid options are: VERTICAL, HORIZONTAL. + type + integer + value + 4 + + CHARACTER_RADIUS + + tooltip + Set collision capsule radius. + type + integer + value + 2 + + CHARACTER_STAY_WITHIN_PARCEL + + tooltip + Determines whether a character can leave its starting parcel.\nTakes a boolean parameter. If TRUE, the character cannot voluntarilly leave the parcel, but can return to it. + type + integer + value + 15 + + CHARACTER_TYPE + + tooltip + Specifies which walk-ability coefficient will be used by this character. + type + integer + value + 6 + + CHARACTER_TYPE_A + + tooltip + + type + integer + value + 0 + + CHARACTER_TYPE_B + + tooltip + + type + integer + value + 1 + + CHARACTER_TYPE_C + + tooltip + + type + integer + value + 2 + + CHARACTER_TYPE_D + + tooltip + + type + integer + value + 3 + + CHARACTER_TYPE_NONE + + tooltip + + type + integer + value + 4 + + CLICK_ACTION_BUY + + tooltip + When the prim is clicked, the buy dialog is opened. + type + integer + value + 2 + + CLICK_ACTION_DISABLED + + tooltip + No click action. No touches detected or passed. + type + integer + value + 8 + + CLICK_ACTION_IGNORE + + tooltip + No click action. Object is invisible to the mouse. + type + integer + value + 9 + + CLICK_ACTION_NONE + + tooltip + Performs the default action: when the prim is clicked, touch events are triggered. + type + integer + value + 0 + + CLICK_ACTION_OPEN + + tooltip + When the prim is clicked, the object inventory dialog is opened. + type + integer + value + 4 + + CLICK_ACTION_OPEN_MEDIA + + tooltip + When the prim is touched, the web media dialog is opened. + type + integer + value + 6 + + CLICK_ACTION_PAY + + tooltip + When the prim is clicked, the pay dialog is opened. + type + integer + value + 3 + + CLICK_ACTION_PLAY + + tooltip + When the prim is clicked, html-on-a-prim is enabled? + type + integer + value + 5 + + CLICK_ACTION_SIT + + tooltip + When the prim is clicked, the avatar sits upon it. + type + integer + value + 1 + + CLICK_ACTION_TOUCH + + tooltip + When the prim is clicked, touch events are triggered. + type + integer + value + 0 + + CLICK_ACTION_ZOOM + + tooltip + Zoom in on object when clicked. + type + integer + value + 7 + + COMBAT_CHANNEL + + tooltip + COMBAT_CHANNEL is an integer constant that, when passed to llRegionSay will add the message to the combat log. A script with a chat listen active on COMBAT_CHANNEL may also monitor the combat log. + type + integer + value + 2147483646 + + COMBAT_LOG_ID + + tooltip + + type + string + value + 45e0fcfa-2268-4490-a51c-3e51bdfe80d1 + + CONTENT_TYPE_ATOM + + tooltip + "application/atom+xml" + type + integer + value + 4 + + CONTENT_TYPE_FORM + + tooltip + "application/x-www-form-urlencoded" + type + integer + value + 7 + + CONTENT_TYPE_HTML + + tooltip + "text/html", only valid for embedded browsers on content owned by the person viewing. Falls back to "text/plain" otherwise. + type + integer + value + 1 + + CONTENT_TYPE_JSON + + tooltip + "application/json" + type + integer + value + 5 + + CONTENT_TYPE_LLSD + + tooltip + "application/llsd+xml" + type + integer + value + 6 + + CONTENT_TYPE_RSS + + tooltip + "application/rss+xml" + type + integer + value + 8 + + CONTENT_TYPE_TEXT + + tooltip + "text/plain" + type + integer + value + 0 + + CONTENT_TYPE_XHTML + + tooltip + "application/xhtml+xml" + type + integer + value + 3 + + CONTENT_TYPE_XML + + tooltip + "application/xml" + type + integer + value + 2 + + CONTROL_BACK + + tooltip + Test for the avatar move back control. + type + integer + value + 0x2 + + CONTROL_DOWN + + tooltip + Test for the avatar move down control. + type + integer + value + 0x20 + + CONTROL_FWD + + tooltip + Test for the avatar move forward control. + type + integer + value + 0x1 + + CONTROL_LBUTTON + + tooltip + Test for the avatar left button control. + type + integer + value + 0x10000000 + + CONTROL_LEFT + + tooltip + Test for the avatar move left control. + type + integer + value + 0x4 + + CONTROL_ML_LBUTTON + + tooltip + Test for the avatar left button control while in mouse look. + type + integer + value + 0x40000000 + + CONTROL_RIGHT + + tooltip + Test for the avatar move right control. + type + integer + value + 0x8 + + CONTROL_ROT_LEFT + + tooltip + Test for the avatar rotate left control. + type + integer + value + 0x100 + + CONTROL_ROT_RIGHT + + tooltip + Test for the avatar rotate right control. + type + integer + value + 0x200 + + CONTROL_UP + + tooltip + Test for the avatar move up control. + type + integer + value + 0x10 + + DAMAGEABLE + + tooltip + Objects in world that are able to process damage. + type + integer + value + 0x20 + + DAMAGE_TYPE_ACID + + tooltip + Damage caused by a caustic substance, such as acid + type + integer + value + 1 + + DAMAGE_TYPE_BLUDGEONING + + tooltip + Damage caused by a blunt object, such as a club. + type + integer + value + 2 + + DAMAGE_TYPE_COLD + + tooltip + Damage inflicted by exposure to extreme cold + type + integer + value + 3 + + DAMAGE_TYPE_ELECTRIC + + tooltip + Damage caused by electricity. + type + integer + value + 4 + + DAMAGE_TYPE_EMOTIONAL + + tooltip + + type + integer + value + 14 + + DAMAGE_TYPE_FIRE + + tooltip + Damage inflicted by exposure to heat or flames. + type + integer + value + 5 + + DAMAGE_TYPE_FORCE + + tooltip + Damage inflicted by a great force or impact. + type + integer + value + 6 + + DAMAGE_TYPE_GENERIC + + tooltip + Generic or legacy damage. + type + integer + value + 0 + + DAMAGE_TYPE_IMPACT + + tooltip + System damage generated by imapact with land or a prim. + type + integer + value + -1 + + DAMAGE_TYPE_NECROTIC + + tooltip + Damage caused by a direct assault on life-force + type + integer + value + 7 + + DAMAGE_TYPE_PIERCING + + tooltip + Damage caused by a piercing object such as a bullet, spear, or arrow. + type + integer + value + 8 + + DAMAGE_TYPE_POISON + + tooltip + Damage caused by poison. + type + integer + value + 9 + + DAMAGE_TYPE_PSYCHIC + + tooltip + Damage caused by a direct assault on the mind. + type + integer + value + 10 + + DAMAGE_TYPE_RADIANT + + tooltip + Damage caused by radiation or extreme light. + type + integer + value + 11 + + DAMAGE_TYPE_SLASHING + + tooltip + Damage caused by a slashing object such as a sword or axe. + type + integer + value + 12 + + DAMAGE_TYPE_SONIC + + tooltip + Damage caused by loud noises, like a Crash Worship concert. + type + integer + value + 13 + + DATA_BORN + + tooltip + The date the agent was born, returned in ISO 8601 format of YYYY-MM-DD. + type + integer + value + 3 + + DATA_NAME + + tooltip + The name of the agent. + type + integer + value + 2 + + DATA_ONLINE + + tooltip + TRUE for online, FALSE for offline. + type + integer + value + 1 + + DATA_PAYINFO + + tooltip + + type + integer + value + 8 + + DATA_RATING + + tooltip + + Returns the agent ratings as a comma separated string of six integers. They are: + 1) Positive rated behaviour + 2) Negative rated behaviour + 3) Positive rated appearance + 4) Negative rated appearance + 5) Positive rated building + 6) Negative rated building + + type + integer + value + 4 + + DATA_SIM_POS + + tooltip + + type + integer + value + 5 + + DATA_SIM_RATING + + tooltip + + type + integer + value + 7 + + DATA_SIM_STATUS + + tooltip + + type + integer + value + 6 + + DEBUG_CHANNEL + + tooltip + DEBUG_CHANNEL is an integer constant that, when passed to llSay, llWhisper, or llShout as a channel parameter, will print text to the Script Warning/Error Window. + type + integer + value + 2147483647 + + DEG_TO_RAD + + tooltip + + 0.017453293 - Number of radians per degree. + You can use this to convert degrees to radians by multiplying the degrees by this number. + + type + float + value + 0.017453293 + + DENSITY + + tooltip + Used with llSetPhysicsMaterial to enable the density value. Must be between 1.0 and 22587.0 (in Kg/m^3 -- see if you can figure out what 22587 represents) + type + integer + value + 1 + + DEREZ_DIE + + tooltip + Causes the object to immediately die. + type + integer + value + 0 + + DEREZ_MAKE_TEMP + + tooltip + The object is made temporary and will be cleaned up at some later timer. + type + integer + value + 1 + + ENVIRONMENT_DAYINFO + + tooltip + Day length, offset and progression. + type + integer + value + 200 + + ENV_INVALID_AGENT + + tooltip + Could not find agent with the specified ID + type + integer + value + -4 + + ENV_INVALID_RULE + + tooltip + Attempted to change an unknown property. + type + integer + value + -5 + + ENV_NOT_EXPERIENCE + + tooltip + Attempt to change environments outside an experience. + type + integer + value + -1 + + ENV_NO_ENVIRONMENT + + tooltip + Could not find environmental settings in object inventory. + type + integer + value + -3 + + ENV_NO_EXPERIENCE_LAND + + tooltip + The experience has not been enabled on this land. + type + integer + value + -7 + + ENV_NO_EXPERIENCE_PERMISSION + + tooltip + Agent has not granted permission to change environments. + type + integer + value + -2 + + ENV_NO_PERMISSIONS + + tooltip + Script does not have permission to modify environment. + type + integer + value + -9 + + ENV_THROTTLE + + tooltip + Could not validate values for environment. + type + integer + value + -8 + + ENV_VALIDATION_FAIL + + tooltip + Could not validate values for environment. + type + integer + value + -6 + + EOF + + tooltip + Indicates the last line of a notecard was read. + type + string + value + \\n\\n\\n + + ERR_GENERIC + + tooltip + + type + integer + value + -1 + + ERR_MALFORMED_PARAMS + + tooltip + + type + integer + value + -3 + + ERR_PARCEL_PERMISSIONS + + tooltip + + type + integer + value + -2 + + ERR_RUNTIME_PERMISSIONS + + tooltip + + type + integer + value + -4 + + ERR_THROTTLED + + tooltip + + type + integer + value + -5 + + ESTATE_ACCESS_ALLOWED_AGENT_ADD + + tooltip + Add the agent to this estate's Allowed Residents list. + type + integer + value + 4 + + ESTATE_ACCESS_ALLOWED_AGENT_REMOVE + + tooltip + Remove the agent from this estate's Allowed Residents list. + type + integer + value + 8 + + ESTATE_ACCESS_ALLOWED_GROUP_ADD + + tooltip + Add the group to this estate's Allowed groups list. + type + integer + value + 16 + + ESTATE_ACCESS_ALLOWED_GROUP_REMOVE + + tooltip + Remove the group from this estate's Allowed groups list. + type + integer + value + 32 + + ESTATE_ACCESS_BANNED_AGENT_ADD + + tooltip + Add the agent to this estate's Banned residents list. + type + integer + value + 64 + + ESTATE_ACCESS_BANNED_AGENT_REMOVE + + tooltip + Remove the agent from this estate's Banned residents list. + type + integer + value + 128 + + FALSE + + tooltip + An integer constant for boolean comparisons. Has the value '0'. + type + integer + value + 0 + + FILTER_FLAGS + + tooltip + Flags to control returned attachments. + type + integer + value + 2 + + FILTER_FLAG_HUDS + + tooltip + Include HUDs with matching experience. + type + integer + value + 0x0001 + + FILTER_INCLUDE + + tooltip + Include attachment point. + type + integer + value + 1 + + FORCE_DIRECT_PATH + + tooltip + Makes character navigate in a straight line toward position. May be set to TRUE or FALSE. + type + integer + value + 1 + + FRICTION + + tooltip + Used with llSetPhysicsMaterial to enable the friction value. Must be between 0.0 and 255.0 + type + integer + value + 2 + + GAME_CONTROL_AXIS_LEFTX + + tooltip + + type + integer + value + 0 + + GAME_CONTROL_AXIS_LEFTY + + tooltip + + type + integer + value + 1 + + GAME_CONTROL_AXIS_RIGHTX + + tooltip + + type + integer + value + 2 + + GAME_CONTROL_AXIS_RIGHTY + + tooltip + + type + integer + value + 3 + + GAME_CONTROL_AXIS_TRIGGERLEFT + + tooltip + + type + integer + value + 4 + + GAME_CONTROL_AXIS_TRIGGERRIGHT + + tooltip + + type + integer + value + 5 + + GAME_CONTROL_BUTTON_A + + tooltip + + type + integer + value + 0x1 + + GAME_CONTROL_BUTTON_B + + tooltip + + type + integer + value + 0x2 + + GAME_CONTROL_BUTTON_BACK + + tooltip + + type + integer + value + 0x10 + + GAME_CONTROL_BUTTON_DPAD_DOWN + + tooltip + + type + integer + value + 0x1000 + + GAME_CONTROL_BUTTON_DPAD_LEFT + + tooltip + + type + integer + value + 0x2000 + + GAME_CONTROL_BUTTON_DPAD_RIGHT + + tooltip + + type + integer + value + 0x4000 + + GAME_CONTROL_BUTTON_DPAD_UP + + tooltip + + type + integer + value + 0x800 + + GAME_CONTROL_BUTTON_GUIDE + + tooltip + + type + integer + value + 0x20 + + GAME_CONTROL_BUTTON_LEFTSHOULDER + + tooltip + + type + integer + value + 0x200 + + GAME_CONTROL_BUTTON_LEFTSTICK + + tooltip + + type + integer + value + 0x80 + + GAME_CONTROL_BUTTON_MISC1 + + tooltip + + type + integer + value + 0x8000 + + GAME_CONTROL_BUTTON_PADDLE1 + + tooltip + + type + integer + value + 0x10000 + + GAME_CONTROL_BUTTON_PADDLE2 + + tooltip + + type + integer + value + 0x20000 + + GAME_CONTROL_BUTTON_PADDLE3 + + tooltip + + type + integer + value + 0x40000 + + GAME_CONTROL_BUTTON_PADDLE4 + + tooltip + + type + integer + value + 0x80000 + + GAME_CONTROL_BUTTON_RIGHTSHOULDER + + tooltip + + type + integer + value + 0x400 + + GAME_CONTROL_BUTTON_RIGHTSTICK + + tooltip + + type + integer + value + 0x100 + + GAME_CONTROL_BUTTON_START + + tooltip + + type + integer + value + 0x40 + + GAME_CONTROL_BUTTON_TOUCHPAD + + tooltip + + type + integer + value + 0x100000 + + GAME_CONTROL_BUTTON_X + + tooltip + + type + integer + value + 0x4 + + GAME_CONTROL_BUTTON_Y + + tooltip + + type + integer + value + 0x8 + + GCNP_RADIUS + + tooltip + + type + integer + value + 0 + + GCNP_STATIC + + tooltip + + type + integer + value + 1 + + GRAVITY_MULTIPLIER + + tooltip + Used with llSetPhysicsMaterial to enable the gravity multiplier value. Must be between -1.0 and +28.0 + type + integer + value + 8 + + HORIZONTAL + + tooltip + + type + integer + value + 1 + + HTTP_ACCEPT + + tooltip + + Provide a string value to be included in the HTTP + accepts header value. This replaces the default Second Life HTTP accepts header. + + type + integer + value + 8 + + HTTP_BODY_MAXLENGTH + + tooltip + + type + integer + value + 2 + + HTTP_BODY_TRUNCATED + + tooltip + + type + integer + value + 0 + + HTTP_CUSTOM_HEADER + + tooltip + Add an extra custom HTTP header to the request. The first string is the name of the parameter to change, e.g. "Pragma", and the second string is the value, e.g. "no-cache". Up to 8 custom headers may be configured per request. Note that certain headers, such as the default headers, are blocked for security reasons. + type + integer + value + 5 + + HTTP_EXTENDED_ERROR + + tooltip + Report extended error information through http_response event. + type + integer + value + 9 + + HTTP_METHOD + + tooltip + + type + integer + value + 0 + + HTTP_MIMETYPE + + tooltip + + type + integer + value + 1 + + HTTP_PRAGMA_NO_CACHE + + tooltip + Allows enabling/disbling of the "Pragma: no-cache" header.\nUsage: [HTTP_PRAGMA_NO_CACHE, integer SendHeader]. When SendHeader is TRUE, the "Pragma: no-cache" header is sent by the script. This matches the default behavior. When SendHeader is FALSE, no "Pragma" header is sent by the script. + type + integer + value + 6 + + HTTP_USER_AGENT + + tooltip + + Provide a string value to be included in the HTTP + User-Agent header value. This is appended to the default value. + + type + integer + value + 7 + + HTTP_VERBOSE_THROTTLE + + tooltip + + type + integer + value + 4 + + HTTP_VERIFY_CERT + + tooltip + + type + integer + value + 3 + + IMG_USE_BAKED_AUX1 + + tooltip + + type + string + value + 9742065b-19b5-297c-858a-29711d539043 + + IMG_USE_BAKED_AUX2 + + tooltip + + type + string + value + 03642e83-2bd1-4eb9-34b4-4c47ed586d2d + + IMG_USE_BAKED_AUX3 + + tooltip + + type + string + value + edd51b77-fc10-ce7a-4b3d-011dfc349e4f + + IMG_USE_BAKED_EYES + + tooltip + + type + string + value + 52cc6bb6-2ee5-e632-d3ad-50197b1dcb8a + + IMG_USE_BAKED_HAIR + + tooltip + + type + string + value + 09aac1fb-6bce-0bee-7d44-caac6dbb6c63 + + IMG_USE_BAKED_HEAD + + tooltip + + type + string + value + 5a9f4a74-30f2-821c-b88d-70499d3e7183 + + IMG_USE_BAKED_LEFTARM + + tooltip + + type + string + value + ff62763f-d60a-9855-890b-0c96f8f8cd98 + + IMG_USE_BAKED_LEFTLEG + + tooltip + + type + string + value + 8e915e25-31d1-cc95-ae08-d58a47488251 + + IMG_USE_BAKED_LOWER + + tooltip + + type + string + value + 24daea5f-0539-cfcf-047f-fbc40b2786ba + + IMG_USE_BAKED_SKIRT + + tooltip + + type + string + value + 43529ce8-7faa-ad92-165a-bc4078371687 + + IMG_USE_BAKED_UPPER + + tooltip + + type + string + value + ae2de45c-d252-50b8-5c6e-19f39ce79317 + + INVENTORY_ALL + + tooltip + + type + integer + value + -1 + + INVENTORY_ANIMATION + + tooltip + + type + integer + value + 20 + + INVENTORY_BODYPART + + tooltip + + type + integer + value + 13 + + INVENTORY_CLOTHING + + tooltip + + type + integer + value + 5 + + INVENTORY_GESTURE + + tooltip + + type + integer + value + 21 + + INVENTORY_LANDMARK + + tooltip + + type + integer + value + 3 + + INVENTORY_MATERIAL + + tooltip + + type + integer + value + 57 + + INVENTORY_NONE + + tooltip + + type + integer + value + -1 + + INVENTORY_NOTECARD + + tooltip + + type + integer + value + 7 + + INVENTORY_OBJECT + + tooltip + + type + integer + value + 6 + + INVENTORY_SCRIPT + + tooltip + + type + integer + value + 10 + + INVENTORY_SETTING + + tooltip + + type + integer + value + 56 + + INVENTORY_SOUND + + tooltip + + type + integer + value + 1 + + INVENTORY_TEXTURE + + tooltip + + type + integer + value + 0 + + JSON_APPEND + + tooltip + + type + integer + value + -1 + + JSON_ARRAY + + tooltip + + type + string + value + \\ufdd2 + + JSON_DELETE + + tooltip + + type + string + value + \\ufdd8 + + JSON_FALSE + + tooltip + + type + string + value + \\ufdd7 + + JSON_INVALID + + tooltip + + type + string + value + \\ufdd0 + + JSON_NULL + + tooltip + + type + string + value + \\ufdd5 + + JSON_NUMBER + + tooltip + + type + string + value + \\ufdd3 + + JSON_OBJECT + + tooltip + + type + string + value + \\ufdd1 + + JSON_STRING + + tooltip + + type + string + value + \\ufdd4 + + JSON_TRUE + + tooltip + + type + string + value + \\ufdd6 + + KFM_CMD_PAUSE + + tooltip + For use with KFM_COMMAND. + type + integer + value + 2 + + KFM_CMD_PLAY + + tooltip + For use with KFM_COMMAND. + type + integer + value + 0 + + KFM_CMD_STOP + + tooltip + For use with KFM_COMMAND. + type + integer + value + 1 + + KFM_COMMAND + + tooltip + + type + integer + value + 0 + + KFM_DATA + + tooltip + + type + integer + value + 2 + + KFM_FORWARD + + tooltip + For use with KFM_MODE. + type + integer + value + 0 + + KFM_LOOP + + tooltip + For use with KFM_MODE. + type + integer + value + 1 + + KFM_MODE + + tooltip + + type + integer + value + 1 + + KFM_PING_PONG + + tooltip + For use with KFM_MODE. + type + integer + value + 2 + + KFM_REVERSE + + tooltip + For use with KFM_MODE. + type + integer + value + 3 + + KFM_ROTATION + + tooltip + For use with KFM_DATA. + type + integer + value + 1 + + KFM_TRANSLATION + + tooltip + For use with KFM_DATA. + type + integer + value + 2 + + LAND_LARGE_BRUSH + + tooltip + Use a large brush size.\nNOTE: This value is incorrect, a large brush should be 2. + type + integer + value + 3 + + LAND_LEVEL + + tooltip + Action to level the land. + type + integer + value + 0 + + LAND_LOWER + + tooltip + Action to lower the land. + type + integer + value + 2 + + LAND_MEDIUM_BRUSH + + tooltip + Use a medium brush size.\nNOTE: This value is incorrect, a medium brush should be 1. + type + integer + value + 2 + + LAND_NOISE + + tooltip + + type + integer + value + 4 + + LAND_RAISE + + tooltip + Action to raise the land. + type + integer + value + 1 + + LAND_REVERT + + tooltip + + type + integer + value + 5 + + LAND_SMALL_BRUSH + + tooltip + Use a small brush size.\nNOTE: This value is incorrect, a small brush should be 0. + type + integer + value + 1 + + LAND_SMOOTH + + tooltip + + type + integer + value + 3 + + LINKSETDATA_DELETE + + tooltip + A name:value pair has been removed from the linkset datastore. + type + integer + value + 2 + + LINKSETDATA_EMEMORY + + tooltip + A name:value pair was too large to write to the linkset datastore. + type + integer + value + 1 + + LINKSETDATA_ENOKEY + + tooltip + The key supplied was empty. + type + integer + value + 2 + + LINKSETDATA_EPROTECTED + + tooltip + The name:value pair has been protected from overwrite in the linkset datastore. + type + integer + value + 3 + + LINKSETDATA_MULTIDELETE + + tooltip + A CSV list of names removed from the linkset datastore. + type + integer + value + 3 + + LINKSETDATA_NOTFOUND + + tooltip + The named key was not found in the datastore. + type + integer + value + 4 + + LINKSETDATA_NOUPDATE + + tooltip + The value written to a name in the keystore is the same as the value already there. + type + integer + value + 5 + + LINKSETDATA_OK + + tooltip + The name:value pair was written to the datastore. + type + integer + value + 0 + + LINKSETDATA_RESET + + tooltip + The linkset datastore has been reset. + type + integer + value + 0 + + LINKSETDATA_UPDATE + + tooltip + A name:value pair in the linkset datastore has been changed or created. + type + integer + value + 1 + + LINK_ALL_CHILDREN + + tooltip + This targets every object except the root in the linked set. + type + integer + value + -3 + + LINK_ALL_OTHERS + + tooltip + This targets every object in the linked set except the object with the script. + type + integer + value + -2 + + LINK_ROOT + + tooltip + This targets the root of the linked set. + type + integer + value + 1 + + LINK_SET + + tooltip + This targets every object in the linked set. + type + integer + value + -1 + + LINK_THIS + + tooltip + The link number of the prim containing the script. + type + integer + value + -4 + + LIST_STAT_GEOMETRIC_MEAN + + tooltip + + type + integer + value + 9 + + LIST_STAT_MAX + + tooltip + + type + integer + value + 2 + + LIST_STAT_MEAN + + tooltip + + type + integer + value + 3 + + LIST_STAT_MEDIAN + + tooltip + + type + integer + value + 4 + + LIST_STAT_MIN + + tooltip + + type + integer + value + 1 + + LIST_STAT_NUM_COUNT + + tooltip + + type + integer + value + 8 + + LIST_STAT_RANGE + + tooltip + + type + integer + value + 0 + + LIST_STAT_STD_DEV + + tooltip + + type + integer + value + 5 + + LIST_STAT_SUM + + tooltip + + type + integer + value + 6 + + LIST_STAT_SUM_SQUARES + + tooltip + + type + integer + value + 7 + + LOOP + + tooltip + Loop the texture animation. + type + integer + value + 0x2 + + MASK_BASE + + tooltip + + type + integer + value + 0 + + MASK_COMBINED + + tooltip + Fold permissions for object inventory into results. + type + integer + value + 0x10 + + MASK_EVERYONE + + tooltip + + type + integer + value + 3 + + MASK_GROUP + + tooltip + + type + integer + value + 2 + + MASK_NEXT + + tooltip + + type + integer + value + 4 + + MASK_OWNER + + tooltip + + type + integer + value + 1 + + NAK + + tooltip + Indicates a notecard read was attempted and the notecard was not yet cached on the server. + type + string + value + \\n\\x15\\n + + NULL_KEY + + tooltip + + type + string + value + 00000000-0000-0000-0000-000000000000 + + OBJECT_ACCOUNT_LEVEL + + tooltip + Retrieves the account level of an avatar.\nReturns 0 when the avatar has a basic account,\n 1 when the avatar has a premium account,\n 10 when the avatar has a premium plus account,\n or -1 if the object is not an avatar. + type + integer + value + 41 + + OBJECT_ANIMATED_COUNT + + tooltip + This is a flag used with llGetObjectDetails to get the number of associated animated objects + type + integer + value + 39 + + OBJECT_ANIMATED_SLOTS_AVAILABLE + + tooltip + This is a flag used with llGetObjectDetails to get the number of additional animated object attachments allowed. + type + integer + value + 40 + + OBJECT_ATTACHED_POINT + + tooltip + Gets the attachment point to which the object is attached.\nReturns 0 if the object is not an attachment (or is an avatar, etc). + type + integer + value + 19 + + OBJECT_ATTACHED_SLOTS_AVAILABLE + + tooltip + Returns the number of attachment slots available.\nReturns 0 if the object is not an avatar or none are available. + type + integer + value + 35 + + OBJECT_BODY_SHAPE_TYPE + + tooltip + This is a flag used with llGetObjectDetails to get the body type of the avatar, based on shape data.\nIf no data is available, -1.0 is returned.\nThis is normally between 0 and 1.0, with 0.5 and larger considered 'male' + type + integer + value + 26 + + OBJECT_CHARACTER_TIME + + tooltip + Units in seconds + type + integer + value + 17 + + OBJECT_CLICK_ACTION + + tooltip + This is a flag used with llGetObjectDetails to get the click action.\nThe default is 0 + type + integer + value + 28 + + OBJECT_CREATION_TIME + + tooltip + This is a flag used with llGetObjectDetails to get the time this object was created + type + integer + value + 36 + + OBJECT_CREATOR + + tooltip + Gets the object's creator key. If id is an avatar, a NULL_KEY is returned. + type + integer + value + 8 + + OBJECT_DAMAGE + + tooltip + Gets the damage value assigned to this object. + type + integer + value + 51 + + OBJECT_DAMAGE_TYPE + + tooltip + Gets the damage type, if any, assigned to this object. + type + integer + value + 52 + + OBJECT_DESC + + tooltip + Gets the object's description. If id is an avatar, an empty string is returned. + type + integer + value + 2 + + OBJECT_GROUP + + tooltip + Gets the prims's group key. If id is an avatar, a NULL_KEY is returned. + type + integer + value + 7 + + OBJECT_GROUP_TAG + + tooltip + Gets the agent's current group role tag. If id is an object, an empty is returned. + type + integer + value + 33 + + OBJECT_HEALTH + + tooltip + Gets current health value for the object. + type + integer + value + 50 + + OBJECT_HOVER_HEIGHT + + tooltip + This is a flag used with llGetObjectDetails to get hover height of the avatar\nIf no data is available, 0.0 is returned. + type + integer + value + 25 + + OBJECT_LAST_OWNER_ID + + tooltip + Gets the object's last owner ID. + type + integer + value + 27 + + OBJECT_LINK_NUMBER + + tooltip + Gets the object's link number or 0 if unlinked. + type + integer + value + 46 + + OBJECT_MASS + + tooltip + Get the object's mass + type + integer + value + 43 + + OBJECT_MATERIAL + + tooltip + Get an object's material setting. + type + integer + value + 42 + + OBJECT_NAME + + tooltip + Gets the object's name. + type + integer + value + 1 + + OBJECT_OMEGA + + tooltip + Gets an object's angular velocity. + type + integer + value + 29 + + OBJECT_OWNER + + tooltip + Gets an object's owner's key. If id is group owned, a NULL_KEY is returned. + type + integer + value + 6 + + OBJECT_PATHFINDING_TYPE + + tooltip + Returns the pathfinding setting of any object in the region. It returns an integer matching one of the OPT_* constants. + type + integer + value + 20 + + OBJECT_PERMS + + tooltip + Gets the objects permissions + type + integer + value + 53 + + OBJECT_PERMS_COMBINED + + tooltip + Gets the object's permissions including any inventory. + type + integer + value + 54 + + OBJECT_PHANTOM + + tooltip + Returns boolean, detailing if phantom is enabled or disabled on the object.\nIf id is an avatar or attachment, 0 is returned. + type + integer + value + 22 + + OBJECT_PHYSICS + + tooltip + Returns boolean, detailing if physics is enabled or disabled on the object.\nIf id is an avatar or attachment, 0 is returned. + type + integer + value + 21 + + OBJECT_PHYSICS_COST + + tooltip + + type + integer + value + 16 + + OBJECT_POS + + tooltip + Gets the object's position in region coordinates. + type + integer + value + 3 + + OBJECT_PRIM_COUNT + + tooltip + Gets the prim count of the object. The script and target object must be owned by the same owner + type + integer + value + 30 + + OBJECT_PRIM_EQUIVALENCE + + tooltip + + type + integer + value + 13 + + OBJECT_RENDER_WEIGHT + + tooltip + This is a flag used with llGetObjectDetails to get the Avatar_Rendering_Cost of an avatar, based on values reported by nearby viewers.\nIf no data is available, -1 is returned.\nThe maximum render weight stored by the simulator is 500000. When called against an object, 0 is returned. + type + integer + value + 24 + + OBJECT_RETURN_PARCEL + + tooltip + + type + integer + value + 1 + + OBJECT_RETURN_PARCEL_OWNER + + tooltip + + type + integer + value + 2 + + OBJECT_RETURN_REGION + + tooltip + + type + integer + value + 4 + + OBJECT_REZZER_KEY + + tooltip + + type + integer + value + 32 + + OBJECT_REZ_TIME + + tooltip + Get the time when an object was rezzed. + type + integer + value + 45 + + OBJECT_ROOT + + tooltip + Gets the id of the root prim of the object requested.\nIf id is an avatar, return the id of the root prim of the linkset the avatar is sitting on (or the avatar's own id if the avatar is not sitting on an object within the region). + type + integer + value + 18 + + OBJECT_ROT + + tooltip + Gets the object's rotation. + type + integer + value + 4 + + OBJECT_RUNNING_SCRIPT_COUNT + + tooltip + + type + integer + value + 9 + + OBJECT_SCALE + + tooltip + Gets the object's size. + type + integer + value + 47 + + OBJECT_SCRIPT_MEMORY + + tooltip + + type + integer + value + 11 + + OBJECT_SCRIPT_TIME + + tooltip + + type + integer + value + 12 + + OBJECT_SELECT_COUNT + + tooltip + This is a flag used with llGetObjectDetails to get the number of avatars selecting any part of the object + type + integer + value + 37 + + OBJECT_SERVER_COST + + tooltip + + type + integer + value + 14 + + OBJECT_SIT_COUNT + + tooltip + This is a flag used with llGetObjectDetails to get the number of avatars sitting on the object + type + integer + value + 38 + + OBJECT_STREAMING_COST + + tooltip + + type + integer + value + 15 + + OBJECT_TEMP_ATTACHED + + tooltip + Returns boolean, indicating if object is a temp attachment. + type + integer + value + 34 + + OBJECT_TEMP_ON_REZ + + tooltip + Returns boolean, detailing if temporary is enabled or disabled on the object. + type + integer + value + 23 + + OBJECT_TEXT + + tooltip + Gets an objects hover text. + type + integer + value + 44 + + OBJECT_TEXT_ALPHA + + tooltip + Gets the alpha of an objects hover text. + type + integer + value + 49 + + OBJECT_TEXT_COLOR + + tooltip + Gets the color of an objects hover text. + type + integer + value + 48 + + OBJECT_TOTAL_INVENTORY_COUNT + + tooltip + Gets the total inventory count of the object. The script and target object must be owned by the same owner + type + integer + value + 31 + + OBJECT_TOTAL_SCRIPT_COUNT + + tooltip + + type + integer + value + 10 + + OBJECT_UNKNOWN_DETAIL + + tooltip + + type + integer + value + -1 + + OBJECT_VELOCITY + + tooltip + Gets the object's velocity. + type + integer + value + 5 + + OPT_AVATAR + + tooltip + Returned for avatars. + type + integer + value + 1 + + OPT_CHARACTER + + tooltip + Returned for pathfinding characters. + type + integer + value + 2 + + OPT_EXCLUSION_VOLUME + + tooltip + Returned for exclusion volumes. + type + integer + value + 6 + + OPT_LEGACY_LINKSET + + tooltip + Returned for movable obstacles, movable phantoms, physical, and volumedetect objects. + type + integer + value + 0 + + OPT_MATERIAL_VOLUME + + tooltip + Returned for material volumes. + type + integer + value + 5 + + OPT_OTHER + + tooltip + Returned for attachments, Linden trees, and grass. + type + integer + value + -1 + + OPT_STATIC_OBSTACLE + + tooltip + Returned for static obstacles. + type + integer + value + 4 + + OPT_WALKABLE + + tooltip + Returned for walkable objects. + type + integer + value + 3 + + PARCEL_COUNT_GROUP + + tooltip + + type + integer + value + 2 + + PARCEL_COUNT_OTHER + + tooltip + + type + integer + value + 3 + + PARCEL_COUNT_OWNER + + tooltip + + type + integer + value + 1 + + PARCEL_COUNT_SELECTED + + tooltip + + type + integer + value + 4 + + PARCEL_COUNT_TEMP + + tooltip + + type + integer + value + 5 + + PARCEL_COUNT_TOTAL + + tooltip + + type + integer + value + 0 + + PARCEL_DETAILS_AREA + + tooltip + The parcel's area, in square meters. (5 chars.). + type + integer + value + 4 + + PARCEL_DETAILS_DESC + + tooltip + The description of the parcel. (127 chars). + type + integer + value + 1 + + PARCEL_DETAILS_FLAGS + + tooltip + Flags set on the parcel + type + integer + value + 12 + + PARCEL_DETAILS_GROUP + + tooltip + The parcel group's key. (36 chars.). + type + integer + value + 3 + + PARCEL_DETAILS_ID + + tooltip + The parcel's key. (36 chars.). + type + integer + value + 5 + + PARCEL_DETAILS_LANDING_LOOKAT + + tooltip + Lookat vector set for teleport routing. + type + integer + value + 10 + + PARCEL_DETAILS_LANDING_POINT + + tooltip + The parcel's landing point, if any. + type + integer + value + 9 + + PARCEL_DETAILS_NAME + + tooltip + The name of the parcel. (63 chars.). + type + integer + value + 0 + + PARCEL_DETAILS_OWNER + + tooltip + The parcel owner's key. (36 chars.). + type + integer + value + 2 + + PARCEL_DETAILS_PRIM_CAPACITY + + tooltip + The parcel's prim capacity. + type + integer + value + 7 + + PARCEL_DETAILS_PRIM_USED + + tooltip + The number of prims used on this parcel. + type + integer + value + 8 + + PARCEL_DETAILS_SCRIPT_DANGER + + tooltip + There are restrictions on this parcel that may impact script execution. + type + integer + value + 13 + + PARCEL_DETAILS_SEE_AVATARS + + tooltip + The parcel's avatar visibility setting. (1 char.). + type + integer + value + 6 + + PARCEL_DETAILS_TP_ROUTING + + tooltip + Parcel's teleport routing setting. + type + integer + value + 11 + + PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY + + tooltip + + type + integer + value + 0x08000000 + + PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS + + tooltip + + type + integer + value + 0x4000000 + + PARCEL_FLAG_ALLOW_CREATE_OBJECTS + + tooltip + + type + integer + value + 0x40 + + PARCEL_FLAG_ALLOW_DAMAGE + + tooltip + + type + integer + value + 0x20 + + PARCEL_FLAG_ALLOW_FLY + + tooltip + + type + integer + value + 0x1 + + PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY + + tooltip + + type + integer + value + 0x10000000 + + PARCEL_FLAG_ALLOW_GROUP_SCRIPTS + + tooltip + + type + integer + value + 0x2000000 + + PARCEL_FLAG_ALLOW_LANDMARK + + tooltip + + type + integer + value + 0x8 + + PARCEL_FLAG_ALLOW_SCRIPTS + + tooltip + + type + integer + value + 0x2 + + PARCEL_FLAG_ALLOW_TERRAFORM + + tooltip + + type + integer + value + 0x10 + + PARCEL_FLAG_LOCAL_SOUND_ONLY + + tooltip + + type + integer + value + 0x8000 + + PARCEL_FLAG_RESTRICT_PUSHOBJECT + + tooltip + + type + integer + value + 0x200000 + + PARCEL_FLAG_USE_ACCESS_GROUP + + tooltip + + type + integer + value + 0x100 + + PARCEL_FLAG_USE_ACCESS_LIST + + tooltip + + type + integer + value + 0x200 + + PARCEL_FLAG_USE_BAN_LIST + + tooltip + + type + integer + value + 0x400 + + PARCEL_FLAG_USE_LAND_PASS_LIST + + tooltip + + type + integer + value + 0x800 + + PARCEL_MEDIA_COMMAND_AGENT + + tooltip + + type + integer + value + 7 + + PARCEL_MEDIA_COMMAND_AUTO_ALIGN + + tooltip + + type + integer + value + 9 + + PARCEL_MEDIA_COMMAND_DESC + + tooltip + Use this to get or set the parcel media description. + type + integer + value + 12 + + PARCEL_MEDIA_COMMAND_LOOP + + tooltip + + type + integer + value + 3 + + PARCEL_MEDIA_COMMAND_LOOP_SET + + tooltip + Used to get or set the parcel's media looping variable. + type + integer + value + 13 + + PARCEL_MEDIA_COMMAND_PAUSE + + tooltip + + type + integer + value + 1 + + PARCEL_MEDIA_COMMAND_PLAY + + tooltip + + type + integer + value + 2 + + PARCEL_MEDIA_COMMAND_SIZE + + tooltip + Use this to get or set the parcel media pixel resolution. + type + integer + value + 11 + + PARCEL_MEDIA_COMMAND_STOP + + tooltip + + type + integer + value + 0 + + PARCEL_MEDIA_COMMAND_TEXTURE + + tooltip + + type + integer + value + 4 + + PARCEL_MEDIA_COMMAND_TIME + + tooltip + + type + integer + value + 6 + + PARCEL_MEDIA_COMMAND_TYPE + + tooltip + Use this to get or set the parcel media MIME type (e.g. "text/html"). + type + integer + value + 10 + + PARCEL_MEDIA_COMMAND_UNLOAD + + tooltip + + type + integer + value + 8 + + PARCEL_MEDIA_COMMAND_URL + + tooltip + + type + integer + value + 5 + + PASSIVE + + tooltip + Static in-world objects. + type + integer + value + 0x4 + + PASS_ALWAYS + + tooltip + Always pass the event. + type + integer + value + 1 + + PASS_IF_NOT_HANDLED + + tooltip + Pass the event if there is no script handling the event in the prim. + type + integer + value + 0 + + PASS_NEVER + + tooltip + Always pass the event. + type + integer + value + 2 + + PATROL_PAUSE_AT_WAYPOINTS + + tooltip + + type + integer + value + 0 + + PAYMENT_INFO_ON_FILE + + tooltip + + type + integer + value + 1 + + PAYMENT_INFO_USED + + tooltip + + type + integer + value + 2 + + PAY_DEFAULT + + tooltip + + type + integer + value + -2 + + PAY_HIDE + + tooltip + + type + integer + value + -1 + + PERMISSION_ATTACH + + tooltip + If this permission is enabled, the object can successfully call llAttachToAvatar to attach to the given avatar. + type + integer + value + 0x20 + + PERMISSION_CHANGE_JOINTS + + tooltip + (not yet implemented) + type + integer + value + 0x100 + + PERMISSION_CHANGE_LINKS + + tooltip + If this permission is enabled, the object can successfully call llCreateLink, llBreakLink, and llBreakAllLinks to change links to other objects. + type + integer + value + 0x80 + + PERMISSION_CHANGE_PERMISSIONS + + tooltip + (not yet implemented) + type + integer + value + 0x200 + + PERMISSION_CONTROL_CAMERA + + tooltip + + type + integer + value + 0x800 + + PERMISSION_DEBIT + + tooltip + If this permission is enabled, the object can successfully call llGiveMoney or llTransferLindenDollars to debit the owners account. + type + integer + value + 0x2 + + PERMISSION_OVERRIDE_ANIMATIONS + + tooltip + Permission to override default animations. + type + integer + value + 0x8000 + + PERMISSION_RELEASE_OWNERSHIP + + tooltip + (not yet implemented) + type + integer + value + 0x40 + + PERMISSION_REMAP_CONTROLS + + tooltip + (not yet implemented) + type + integer + value + 0x8 + + PERMISSION_RETURN_OBJECTS + + tooltip + + type + integer + value + 65536 + + PERMISSION_SILENT_ESTATE_MANAGEMENT + + tooltip + A script with this permission does not notify the object owner when it modifies estate access rules via llManageEstateAccess. + type + integer + value + 0x4000 + + PERMISSION_TAKE_CONTROLS + + tooltip + If this permission enabled, the object can successfully call the llTakeControls libray call. + type + integer + value + 0x4 + + PERMISSION_TELEPORT + + tooltip + + type + integer + value + 0x1000 + + PERMISSION_TRACK_CAMERA + + tooltip + + type + integer + value + 0x400 + + PERMISSION_TRIGGER_ANIMATION + + tooltip + If this permission is enabled, the object can successfully call llStartAnimation for the avatar that owns this. + type + integer + value + 0x10 + + PERM_ALL + + tooltip + + type + integer + value + 0x7FFFFFFF + + PERM_COPY + + tooltip + + type + integer + value + 0x8000 + + PERM_MODIFY + + tooltip + + type + integer + value + 0x4000 + + PERM_MOVE + + tooltip + + type + integer + value + 0x80000 + + PERM_TRANSFER + + tooltip + + type + integer + value + 0x2000 + + PI + + tooltip + 3.14159265 - The number of radians in a semi-circle. + type + float + value + 3.14159265 + + PING_PONG + + tooltip + Play animation going forwards, then backwards. + type + integer + value + 0x8 + + PI_BY_TWO + + tooltip + 1.57079633 - The number of radians in a quarter circle. + type + float + value + 1.57079633 + + PRIM_ALLOW_UNSIT + + tooltip + Prim parameter for restricting manual standing for seated avatars in an experience.\nIgnored if the avatar was not seated via a call to llSitOnLink. + type + integer + value + 39 + + PRIM_ALPHA_MODE + + tooltip + Prim parameter for materials using integer face, integer alpha_mode, integer alpha_cutoff.\nDefines how the alpha channel of the diffuse texture should be rendered.\nValid options for alpha_mode are PRIM_ALPHA_MODE_BLEND, _NONE, _MASK, and _EMISSIVE.\nalpha_cutoff is used only for PRIM_ALPHA_MODE_MASK. + type + integer + value + 38 + + PRIM_ALPHA_MODE_BLEND + + tooltip + Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as alpha-blended. + type + integer + value + 1 + + PRIM_ALPHA_MODE_EMISSIVE + + tooltip + Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as an emissivity mask. + type + integer + value + 3 + + PRIM_ALPHA_MODE_MASK + + tooltip + Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be rendered as fully opaque for alpha values above alpha_cutoff and fully transparent otherwise. + type + integer + value + 2 + + PRIM_ALPHA_MODE_NONE + + tooltip + Prim parameter setting for PRIM_ALPHA_MODE.\nIndicates that the diffuse texture's alpha channel should be ignored. + type + integer + value + 0 + + PRIM_BUMP_BARK + + tooltip + + type + integer + value + 4 + + PRIM_BUMP_BLOBS + + tooltip + + type + integer + value + 12 + + PRIM_BUMP_BRICKS + + tooltip + + type + integer + value + 5 + + PRIM_BUMP_BRIGHT + + tooltip + + type + integer + value + 1 + + PRIM_BUMP_CHECKER + + tooltip + + type + integer + value + 6 + + PRIM_BUMP_CONCRETE + + tooltip + + type + integer + value + 7 + + PRIM_BUMP_DARK + + tooltip + + type + integer + value + 2 + + PRIM_BUMP_DISKS + + tooltip + + type + integer + value + 10 + + PRIM_BUMP_GRAVEL + + tooltip + + type + integer + value + 11 + + PRIM_BUMP_LARGETILE + + tooltip + + type + integer + value + 14 + + PRIM_BUMP_NONE + + tooltip + + type + integer + value + 0 + + PRIM_BUMP_SHINY + + tooltip + + type + integer + value + 19 + + PRIM_BUMP_SIDING + + tooltip + + type + integer + value + 13 + + PRIM_BUMP_STONE + + tooltip + + type + integer + value + 9 + + PRIM_BUMP_STUCCO + + tooltip + + type + integer + value + 15 + + PRIM_BUMP_SUCTION + + tooltip + + type + integer + value + 16 + + PRIM_BUMP_TILE + + tooltip + + type + integer + value + 8 + + PRIM_BUMP_WEAVE + + tooltip + + type + integer + value + 17 + + PRIM_BUMP_WOOD + + tooltip + + type + integer + value + 3 + + PRIM_CAST_SHADOWS + + deprecated + 1 + tooltip + + type + integer + value + 24 + + PRIM_CLICK_ACTION + + tooltip + + type + integer + value + 43 + + PRIM_COLLISION_SOUND + + tooltip + Collision sound uuid and volume for this prim + type + integer + value + 53 + + PRIM_COLOR + + tooltip + + type + integer + value + 18 + + PRIM_DAMAGE + + tooltip + Damage and damage type assigned to this prim. + type + integer + value + 51 + + PRIM_DESC + + tooltip + + type + integer + value + 28 + + PRIM_FLEXIBLE + + tooltip + + type + integer + value + 21 + + PRIM_FULLBRIGHT + + tooltip + + type + integer + value + 20 + + PRIM_GLOW + + tooltip + PRIM_GLOW is used to get or set the glow status of the face. + type + integer + value + 25 + + PRIM_GLTF_ALPHA_MODE_BLEND + + tooltip + Prim parameter setting for PRIM_GLTF_BASE_COLOR alpha mode "BLEND". + type + integer + value + 1 + + PRIM_GLTF_ALPHA_MODE_MASK + + tooltip + Prim parameter setting for PRIM_GLTF_BASE_COLOR alpha mode "MASK". + type + integer + value + 2 + + PRIM_GLTF_ALPHA_MODE_OPAQUE + + tooltip + Prim parameter setting for PRIM_GLTF_BASE_COLOR alpha mode "OPAQUE". + type + integer + value + 0 + + PRIM_GLTF_BASE_COLOR + + tooltip + Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color, integer alpha_mode, integer alpha_cutoff, boolean double_sided.\nValid options for alpha_mode are PRIM_ALPHA_MODE_BLEND, _NONE, and _MASK.\nalpha_cutoff is used only for PRIM_ALPHA_MODE_MASK. + type + integer + value + 48 + + PRIM_GLTF_EMISSIVE + + tooltip + Prim parameter for GLTF materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color + type + integer + value + 46 + + PRIM_GLTF_METALLIC_ROUGHNESS + + tooltip + Prim parameter for GLTF materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, float metallic_factor, float roughness_factor + type + integer + value + 47 + + PRIM_GLTF_NORMAL + + tooltip + Prim parameter for GLTF materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians + type + integer + value + 45 + + PRIM_HEALTH + + tooltip + Health value for this prim + type + integer + value + 52 + + PRIM_HOLE_CIRCLE + + tooltip + + type + integer + value + 0x10 + + PRIM_HOLE_DEFAULT + + tooltip + + type + integer + value + 0x00 + + PRIM_HOLE_SQUARE + + tooltip + + type + integer + value + 0x20 + + PRIM_HOLE_TRIANGLE + + tooltip + + type + integer + value + 0x30 + + PRIM_LINK_TARGET + + tooltip + + type + integer + value + 34 + + PRIM_MATERIAL + + tooltip + + type + integer + value + 2 + + PRIM_MATERIAL_FLESH + + tooltip + + type + integer + value + 4 + + PRIM_MATERIAL_GLASS + + tooltip + + type + integer + value + 2 + + PRIM_MATERIAL_LIGHT + + tooltip + + type + integer + value + 7 + + PRIM_MATERIAL_METAL + + tooltip + + type + integer + value + 1 + + PRIM_MATERIAL_PLASTIC + + tooltip + + type + integer + value + 5 + + PRIM_MATERIAL_RUBBER + + tooltip + + type + integer + value + 6 + + PRIM_MATERIAL_STONE + + tooltip + + type + integer + value + 0 + + PRIM_MATERIAL_WOOD + + tooltip + + type + integer + value + 3 + + PRIM_MEDIA_ALT_IMAGE_ENABLE + + tooltip + Boolean. Gets/Sets the default image state (the image that the user sees before a piece of media is active) for the chosen face. The default image is specified by Second Life's server for that media type. + type + integer + value + 0 + + PRIM_MEDIA_AUTO_LOOP + + tooltip + Boolean. Gets/Sets whether auto-looping is enabled. + type + integer + value + 4 + + PRIM_MEDIA_AUTO_PLAY + + tooltip + Boolean. Gets/Sets whether the media auto-plays when a Resident can view it. + type + integer + value + 5 + + PRIM_MEDIA_AUTO_SCALE + + tooltip + Boolean. Gets/Sets whether auto-scaling is enabled. Auto-scaling forces the media to the full size of the texture. + type + integer + value + 6 + + PRIM_MEDIA_AUTO_ZOOM + + tooltip + Boolean. Gets/Sets whether clicking the media triggers auto-zoom and auto-focus on the media. + type + integer + value + 7 + + PRIM_MEDIA_CONTROLS + + tooltip + Integer. Gets/Sets the style of controls. Can be either PRIM_MEDIA_CONTROLS_STANDARD or PRIM_MEDIA_CONTROLS_MINI. + type + integer + value + 1 + + PRIM_MEDIA_CONTROLS_MINI + + tooltip + Mini web navigation controls; does not include an address bar. + type + integer + value + 1 + + PRIM_MEDIA_CONTROLS_STANDARD + + tooltip + Standard web navigation controls. + type + integer + value + 0 + + PRIM_MEDIA_CURRENT_URL + + tooltip + String. Gets/Sets the current url displayed on the chosen face. Changing this URL causes navigation. 1024 characters Maximum. + type + integer + value + 2 + + PRIM_MEDIA_FIRST_CLICK_INTERACT + + tooltip + Boolean. Gets/Sets whether the first click interaction is enabled. + type + integer + value + 8 + + PRIM_MEDIA_HEIGHT_PIXELS + + tooltip + Integer. Gets/Sets the height of the media in pixels. + type + integer + value + 10 + + PRIM_MEDIA_HOME_URL + + tooltip + String. Gets/Sets the home URL for the chosen face. 1024 characters maximum. + type + integer + value + 3 + + PRIM_MEDIA_MAX_HEIGHT_PIXELS + + tooltip + + type + integer + value + 2048 + + PRIM_MEDIA_MAX_URL_LENGTH + + tooltip + + type + integer + value + 1024 + + PRIM_MEDIA_MAX_WHITELIST_COUNT + + tooltip + + type + integer + value + 64 + + PRIM_MEDIA_MAX_WHITELIST_SIZE + + tooltip + + type + integer + value + 1024 + + PRIM_MEDIA_MAX_WIDTH_PIXELS + + tooltip + + type + integer + value + 2048 + + PRIM_MEDIA_PARAM_MAX + + tooltip + + type + integer + value + 14 + + PRIM_MEDIA_PERMS_CONTROL + + tooltip + Integer. Gets/Sets the permissions mask that control who can see the media control bar above the object:: PRIM_MEDIA_PERM_ANYONE, PRIM_MEDIA_PERM_GROUP, PRIM_MEDIA_PERM_NONE, PRIM_MEDIA_PERM_OWNER + type + integer + value + 14 + + PRIM_MEDIA_PERMS_INTERACT + + tooltip + Integer. Gets/Sets the permissions mask that control who can interact with the object: PRIM_MEDIA_PERM_ANYONE, PRIM_MEDIA_PERM_GROUP, PRIM_MEDIA_PERM_NONE, PRIM_MEDIA_PERM_OWNER + type + integer + value + 13 + + PRIM_MEDIA_PERM_ANYONE + + tooltip + + type + integer + value + 4 + + PRIM_MEDIA_PERM_GROUP + + tooltip + + type + integer + value + 2 + + PRIM_MEDIA_PERM_NONE + + tooltip + + type + integer + value + 0 + + PRIM_MEDIA_PERM_OWNER + + tooltip + + type + integer + value + 1 + + PRIM_MEDIA_WHITELIST + + tooltip + String. Gets/Sets the white-list as a string of escaped, comma-separated URLs. This string can hold up to 64 URLs or 1024 characters, whichever comes first. + type + integer + value + 12 + + PRIM_MEDIA_WHITELIST_ENABLE + + tooltip + Boolean. Gets/Sets whether navigation is restricted to URLs in PRIM_MEDIA_WHITELIST. + type + integer + value + 11 + + PRIM_MEDIA_WIDTH_PIXELS + + tooltip + Integer. Gets/Sets the width of the media in pixels. + type + integer + value + 9 + + PRIM_NAME + + tooltip + + type + integer + value + 27 + + PRIM_NORMAL + + tooltip + Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians + type + integer + value + 37 + + PRIM_OMEGA + + tooltip + + type + integer + value + 32 + + PRIM_PHANTOM + + tooltip + + type + integer + value + 5 + + PRIM_PHYSICS + + tooltip + + type + integer + value + 3 + + PRIM_PHYSICS_SHAPE_CONVEX + + tooltip + Use the convex hull of the prim shape for physics (this is the default for mesh objects). + type + integer + value + 2 + + PRIM_PHYSICS_SHAPE_NONE + + tooltip + Ignore this prim in the physics shape. NB: This cannot be applied to the root prim. + type + integer + value + 1 + + PRIM_PHYSICS_SHAPE_PRIM + + tooltip + Use the normal prim shape for physics (this is the default for all non-mesh objects). + type + integer + value + 0 + + PRIM_PHYSICS_SHAPE_TYPE + + tooltip + + Allows you to set the physics shape type of a prim via lsl. Permitted values are: + PRIM_PHYSICS_SHAPE_NONE, PRIM_PHYSICS_SHAPE_PRIM, PRIM_PHYSICS_SHAPE_CONVEX + + type + integer + value + 30 + + PRIM_POINT_LIGHT + + tooltip + + type + integer + value + 23 + + PRIM_POSITION + + tooltip + + type + integer + value + 6 + + PRIM_POS_LOCAL + + tooltip + + type + integer + value + 33 + + PRIM_PROJECTOR + + tooltip + + type + integer + value + 42 + + PRIM_REFLECTION_PROBE + + tooltip + Allows you to configure the object as a custom-placed reflection probe, for image-based lighting (IBL). Only objects in the influence volume of the reflection probe object are affected. + type + integer + value + 44 + + PRIM_REFLECTION_PROBE_BOX + + tooltip + This is a flag option used with llGetPrimitiveParams and related functions when the parameter is PRIM_REFLECTION_PROBE. When set, the reflection probe is a box. When unset, the reflection probe is a sphere. + type + integer + value + 1 + + PRIM_REFLECTION_PROBE_DYNAMIC + + tooltip + This is a flag option used with llGetPrimitiveParams and related functions when the parameter is PRIM_REFLECTION_PROBE. When set, the reflection probe includes avatars in IBL effects. When unset, the reflection probe excludes avatars. + type + integer + value + 2 + + PRIM_REFLECTION_PROBE_MIRROR + + tooltip + This is a flag option used with llGetPrimitiveParams and related functions when the parameter is PRIM_REFLECTION_PROBE. When set, the reflection probe acts as a mirror. + type + integer + value + 4 + + PRIM_RENDER_MATERIAL + + tooltip + + type + integer + value + 49 + + PRIM_ROTATION + + tooltip + + type + integer + value + 8 + + PRIM_ROT_LOCAL + + tooltip + + type + integer + value + 29 + + PRIM_SCRIPTED_SIT_ONLY + + tooltip + Prim parameter for restricting manual sitting on this prim.\nSitting must be initiated via call to llSitOnLink. + type + integer + value + 40 + + PRIM_SCULPT_FLAG_ANIMESH + + tooltip + Mesh is animated. + type + integer + value + 32 + + PRIM_SCULPT_FLAG_INVERT + + tooltip + Render inside out (inverts the normals). + type + integer + value + 64 + + PRIM_SCULPT_FLAG_MIRROR + + tooltip + Render an X axis mirror of the sculpty. + type + integer + value + 128 + + PRIM_SCULPT_TYPE_CYLINDER + + tooltip + + type + integer + value + 4 + + PRIM_SCULPT_TYPE_MASK + + tooltip + + type + integer + value + 7 + + PRIM_SCULPT_TYPE_MESH + + tooltip + + type + integer + value + 5 + + PRIM_SCULPT_TYPE_PLANE + + tooltip + + type + integer + value + 3 + + PRIM_SCULPT_TYPE_SPHERE + + tooltip + + type + integer + value + 1 + + PRIM_SCULPT_TYPE_TORUS + + tooltip + + type + integer + value + 2 + + PRIM_SHINY_HIGH + + tooltip + + type + integer + value + 3 + + PRIM_SHINY_LOW + + tooltip + + type + integer + value + 1 + + PRIM_SHINY_MEDIUM + + tooltip + + type + integer + value + 2 + + PRIM_SHINY_NONE + + tooltip + + type + integer + value + 0 + + PRIM_SIT_FLAGS + + tooltip + + type + integer + value + 50 + + PRIM_SIT_TARGET + + tooltip + + type + integer + value + 41 + + PRIM_SIZE + + tooltip + + type + integer + value + 7 + + PRIM_SLICE + + tooltip + + type + integer + value + 35 + + PRIM_SPECULAR + + tooltip + Prim parameter for materials using integer face, string texture, vector repeats, vector offsets, float rotation_in_radians, vector color, integer glossy, integer environment + type + integer + value + 36 + + PRIM_TEMP_ON_REZ + + tooltip + + type + integer + value + 4 + + PRIM_TEXGEN + + tooltip + + type + integer + value + 22 + + PRIM_TEXGEN_DEFAULT + + tooltip + + type + integer + value + 0 + + PRIM_TEXGEN_PLANAR + + tooltip + + type + integer + value + 1 + + PRIM_TEXT + + tooltip + + type + integer + value + 26 + + PRIM_TEXTURE + + tooltip + + type + integer + value + 17 + + PRIM_TYPE + + tooltip + + type + integer + value + 9 + + PRIM_TYPE_BOX + + tooltip + + type + integer + value + 0 + + PRIM_TYPE_CYLINDER + + tooltip + + type + integer + value + 1 + + PRIM_TYPE_PRISM + + tooltip + + type + integer + value + 2 + + PRIM_TYPE_RING + + tooltip + + type + integer + value + 6 + + PRIM_TYPE_SCULPT + + tooltip + + type + integer + value + 7 + + PRIM_TYPE_SPHERE + + tooltip + + type + integer + value + 3 + + PRIM_TYPE_TORUS + + tooltip + + type + integer + value + 4 + + PRIM_TYPE_TUBE + + tooltip + + type + integer + value + 5 + + PROFILE_NONE + + tooltip + Disables profiling + type + integer + value + 0 + + PROFILE_SCRIPT_MEMORY + + tooltip + Enables memory profiling + type + integer + value + 1 + + PSYS_PART_BF_DEST_COLOR + + tooltip + + type + integer + value + 2 + + PSYS_PART_BF_ONE + + tooltip + + type + integer + value + 0 + + PSYS_PART_BF_ONE_MINUS_DEST_COLOR + + tooltip + + type + integer + value + 4 + + PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA + + tooltip + + type + integer + value + 9 + + PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR + + tooltip + + type + integer + value + 5 + + PSYS_PART_BF_SOURCE_ALPHA + + tooltip + + type + integer + value + 7 + + PSYS_PART_BF_SOURCE_COLOR + + tooltip + + type + integer + value + 3 + + PSYS_PART_BF_ZERO + + tooltip + + type + integer + value + 1 + + PSYS_PART_BLEND_FUNC_DEST + + tooltip + + type + integer + value + 25 + + PSYS_PART_BLEND_FUNC_SOURCE + + tooltip + + type + integer + value + 24 + + PSYS_PART_BOUNCE_MASK + + tooltip + Particles bounce off of a plane at the objects Z height. + type + integer + value + 0x4 + + PSYS_PART_EMISSIVE_MASK + + tooltip + The particle glows. + type + integer + value + 0x100 + + PSYS_PART_END_ALPHA + + tooltip + A float which determines the ending alpha of the object. + type + integer + value + 4 + + PSYS_PART_END_COLOR + + tooltip + A vector <r, g, b> which determines the ending color of the object. + type + integer + value + 3 + + PSYS_PART_END_GLOW + + tooltip + + type + integer + value + 27 + + PSYS_PART_END_SCALE + + tooltip + A vector <sx, sy, z>, which is the ending size of the particle billboard in meters (z is ignored). + type + integer + value + 6 + + PSYS_PART_FLAGS + + tooltip + Each particle that is emitted by the particle system is simulated based on the following flags. To use multiple flags, bitwise or (|) them together. + type + integer + value + 0 + + PSYS_PART_FOLLOW_SRC_MASK + + tooltip + The particle position is relative to the source objects position. + type + integer + value + 0x10 + + PSYS_PART_FOLLOW_VELOCITY_MASK + + tooltip + The particle orientation is rotated so the vertical axis faces towards the particle velocity. + type + integer + value + 0x20 + + PSYS_PART_INTERP_COLOR_MASK + + tooltip + Interpolate both the color and alpha from the start value to the end value. + type + integer + value + 0x1 + + PSYS_PART_INTERP_SCALE_MASK + + tooltip + Interpolate the particle scale from the start value to the end value. + type + integer + value + 0x2 + + PSYS_PART_MAX_AGE + + tooltip + Age in seconds of a particle at which it dies. + type + integer + value + 7 + + PSYS_PART_RIBBON_MASK + + tooltip + + type + integer + value + 0x400 + + PSYS_PART_START_ALPHA + + tooltip + A float which determines the starting alpha of the object. + type + integer + value + 2 + + PSYS_PART_START_COLOR + + tooltip + A vector <r.r, g.g, b.b> which determines the starting color of the object. + type + integer + value + 1 + + PSYS_PART_START_GLOW + + tooltip + + type + integer + value + 26 + + PSYS_PART_START_SCALE + + tooltip + A vector <sx, sy, z>, which is the starting size of the particle billboard in meters (z is ignored). + type + integer + value + 5 + + PSYS_PART_TARGET_LINEAR_MASK + + tooltip + + type + integer + value + 0x80 + + PSYS_PART_TARGET_POS_MASK + + tooltip + The particle heads towards the location of the target object as defined by PSYS_SRC_TARGET_KEY. + type + integer + value + 0x40 + + PSYS_PART_WIND_MASK + + tooltip + Particles have their velocity damped towards the wind velocity. + type + integer + value + 0x8 + + PSYS_SRC_ACCEL + + tooltip + A vector <x, y, z> which is the acceleration to apply on particles. + type + integer + value + 8 + + PSYS_SRC_ANGLE_BEGIN + + tooltip + Area in radians specifying where particles will NOT be created (for ANGLE patterns) + type + integer + value + 22 + + PSYS_SRC_ANGLE_END + + tooltip + Area in radians filled with particles (for ANGLE patterns) (if lower than PSYS_SRC_ANGLE_BEGIN, acts as PSYS_SRC_ANGLE_BEGIN itself, and PSYS_SRC_ANGLE_BEGIN acts as PSYS_SRC_ANGLE_END). + type + integer + value + 23 + + PSYS_SRC_BURST_PART_COUNT + + tooltip + How many particles to release in a burst. + type + integer + value + 15 + + PSYS_SRC_BURST_RADIUS + + tooltip + What distance from the center of the object to create the particles. + type + integer + value + 16 + + PSYS_SRC_BURST_RATE + + tooltip + How often to release a particle burst (float seconds). + type + integer + value + 13 + + PSYS_SRC_BURST_SPEED_MAX + + tooltip + Maximum speed that a particle should be moving. + type + integer + value + 18 + + PSYS_SRC_BURST_SPEED_MIN + + tooltip + Minimum speed that a particle should be moving. + type + integer + value + 17 + + PSYS_SRC_INNERANGLE + + tooltip + + Specifies the inner angle of the arc created by the PSYS_SRC_PATTERN_ANGLE or PSYS_SRC_PATTERN_ANGLE_CONE source pattern. + The area specified will NOT have particles in it. + + type + integer + value + 10 + + PSYS_SRC_MAX_AGE + + tooltip + How long this particle system should last, 0.0 means forever. + type + integer + value + 19 + + PSYS_SRC_OMEGA + + tooltip + Sets the angular velocity to rotate the axis that SRC_PATTERN_ANGLE and SRC_PATTERN_ANGLE_CONE use. + type + integer + value + 21 + + PSYS_SRC_OUTERANGLE + + tooltip + + Specifies the outer angle of the arc created by the PSYS_SRC_PATTERN_ANGLE or PSYS_SRC_PATTERN_ANGLE_CONE source pattern. + The area between the outer and inner angle will be filled with particles. + + type + integer + value + 11 + + PSYS_SRC_PATTERN + + tooltip + + The pattern which is used to generate particles. + Use one of the following values: PSYS_SRC_PATTERN Values. + + type + integer + value + 9 + + PSYS_SRC_PATTERN_ANGLE + + tooltip + Shoot particles across a 2 dimensional area defined by the arc created from PSYS_SRC_OUTERANGLE. There will be an open area defined by PSYS_SRC_INNERANGLE within the larger arc. + type + integer + value + 0x04 + + PSYS_SRC_PATTERN_ANGLE_CONE + + tooltip + Shoot particles out in a 3 dimensional cone with an outer arc of PSYS_SRC_OUTERANGLE and an inner open area defined by PSYS_SRC_INNERANGLE. + type + integer + value + 0x08 + + PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY + + tooltip + + type + integer + value + 0x10 + + PSYS_SRC_PATTERN_DROP + + tooltip + Drop particles at the source position. + type + integer + value + 0x01 + + PSYS_SRC_PATTERN_EXPLODE + + tooltip + Shoot particles out in all directions, using the burst parameters. + type + integer + value + 0x02 + + PSYS_SRC_TARGET_KEY + + tooltip + The key of a target object to move towards if PSYS_PART_TARGET_POS_MASK is enabled. + type + integer + value + 20 + + PSYS_SRC_TEXTURE + + tooltip + An asset name for the texture to use for the particles. + type + integer + value + 12 + + PUBLIC_CHANNEL + + tooltip + PUBLIC_CHANNEL is an integer constant that, when passed to llSay, llWhisper, or llShout as a channel parameter, will print text to the publicly heard chat channel. + type + integer + value + 0 + + PURSUIT_FUZZ_FACTOR + + tooltip + Selects a random destination near the offset. + type + integer + value + 3 + + PURSUIT_GOAL_TOLERANCE + + tooltip + + type + integer + value + 5 + + PURSUIT_INTERCEPT + + tooltip + Define whether the character attempts to predict the target's location. + type + integer + value + 4 + + PURSUIT_OFFSET + + tooltip + Go to a position offset from the target. + type + integer + value + 1 + + PU_EVADE_HIDDEN + + tooltip + Triggered when an llEvade character thinks it has hidden from its pursuer. + type + integer + value + 0x07 + + PU_EVADE_SPOTTED + + tooltip + Triggered when an llEvade character switches from hiding to running + type + integer + value + 0x08 + + PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED + + tooltip + + type + integer + value + 10 + + PU_FAILURE_INVALID_GOAL + + tooltip + Goal is not on the navigation-mesh and cannot be reached. + type + integer + value + 0x03 + + PU_FAILURE_INVALID_START + + tooltip + Character cannot navigate from the current location - e.g., the character is off the navmesh or too high above it. + type + integer + value + 0x02 + + PU_FAILURE_NO_NAVMESH + + tooltip + This is a fatal error reported to a character when there is no navmesh for the region. This usually indicates a server failure and users should file a bug report and include the time and region in which they received this message. + type + integer + value + 0x09 + + PU_FAILURE_NO_VALID_DESTINATION + + tooltip + There is no good place for the character to go - e.g., it is patrolling and all the patrol points are now unreachable. + type + integer + value + 0x06 + + PU_FAILURE_OTHER + + tooltip + + type + integer + value + 1000000 + + PU_FAILURE_PARCEL_UNREACHABLE + + tooltip + + type + integer + value + 11 + + PU_FAILURE_TARGET_GONE + + tooltip + Target (for llPursue or llEvade) can no longer be tracked - e.g., it left the region or is an avatar that is now more than about 30m outside the region. + type + integer + value + 0x05 + + PU_FAILURE_UNREACHABLE + + tooltip + Goal is no longer reachable for some reason - e.g., an obstacle blocks the path. + type + integer + value + 0x04 + + PU_GOAL_REACHED + + tooltip + Character has reached the goal and will stop or choose a new goal (if wandering). + type + integer + value + 0x01 + + PU_SLOWDOWN_DISTANCE_REACHED + + tooltip + Character is near current goal. + type + integer + value + 0x00 + + RAD_TO_DEG + + tooltip + 57.2957795 - Number of degrees per radian. You can use this number to convert radians to degrees by multiplying the radians by this number. + type + float + value + 57.2957795 + + RCERR_CAST_TIME_EXCEEDED + + tooltip + + type + integer + value + -3 + + RCERR_SIM_PERF_LOW + + tooltip + + type + integer + value + -2 + + RCERR_UNKNOWN + + tooltip + + type + integer + value + -1 + + RC_DATA_FLAGS + + tooltip + + type + integer + value + 2 + + RC_DETECT_PHANTOM + + tooltip + + type + integer + value + 1 + + RC_GET_LINK_NUM + + tooltip + + type + integer + value + 4 + + RC_GET_NORMAL + + tooltip + + type + integer + value + 1 + + RC_GET_ROOT_KEY + + tooltip + + type + integer + value + 2 + + RC_MAX_HITS + + tooltip + + type + integer + value + 3 + + RC_REJECT_AGENTS + + tooltip + + type + integer + value + 1 + + RC_REJECT_LAND + + tooltip + + type + integer + value + 8 + + RC_REJECT_NONPHYSICAL + + tooltip + + type + integer + value + 4 + + RC_REJECT_PHYSICAL + + tooltip + + type + integer + value + 2 + + RC_REJECT_TYPES + + tooltip + + type + integer + value + 0 + + REGION_FLAG_ALLOW_DAMAGE + + tooltip + + type + integer + value + 0x1 + + REGION_FLAG_ALLOW_DIRECT_TELEPORT + + tooltip + + type + integer + value + 0x100000 + + REGION_FLAG_BLOCK_FLY + + tooltip + + type + integer + value + 0x80000 + + REGION_FLAG_BLOCK_FLYOVER + + tooltip + + type + integer + value + 0x8000000 + + REGION_FLAG_BLOCK_TERRAFORM + + tooltip + + type + integer + value + 0x40 + + REGION_FLAG_DISABLE_COLLISIONS + + tooltip + + type + integer + value + 0x1000 + + REGION_FLAG_DISABLE_PHYSICS + + tooltip + + type + integer + value + 0x4000 + + REGION_FLAG_FIXED_SUN + + tooltip + + type + integer + value + 0x10 + + REGION_FLAG_RESTRICT_PUSHOBJECT + + tooltip + + type + integer + value + 0x400000 + + REGION_FLAG_SANDBOX + + tooltip + + type + integer + value + 0x100 + + REMOTE_DATA_CHANNEL + + tooltip + + type + integer + value + 1 + + REMOTE_DATA_REPLY + + tooltip + + type + integer + value + 3 + + REMOTE_DATA_REQUEST + + tooltip + + type + integer + value + 2 + + REQUIRE_LINE_OF_SIGHT + + tooltip + Define whether the character needs a line-of-sight to give chase. + type + integer + value + 2 + + RESTITUTION + + tooltip + Used with llSetPhysicsMaterial to enable the density value. Must be between 0.0 and 1.0 + type + integer + value + 4 + + REVERSE + + tooltip + Play animation in reverse direction. + type + integer + value + 0x4 + + REZ_ACCEL + + tooltip + Acceleration forced applied to the rezzed object. [vector force, integer rel] + type + integer + value + 5 + + REZ_DAMAGE + + tooltip + Damage applied by the object when it collides with an agent. [float damage] + type + integer + value + 8 + + REZ_DAMAGE_TYPE + + tooltip + Set the damage type applied when this object collides. + type + integer + value + 12 + + REZ_FLAGS + + tooltip + Rez flags to set on the newly rezzed object. [integer flags] + type + integer + value + 1 + + REZ_FLAG_BLOCK_GRAB_OBJECT + + tooltip + Prevent grabbing the object. + type + integer + value + 0x0080 + + REZ_FLAG_DIE_ON_COLLIDE + + tooltip + Object will die after its first collision. + type + integer + value + 0x0008 + + REZ_FLAG_DIE_ON_NOENTRY + + tooltip + Object will die if it attempts to enter a parcel that it can not. + type + integer + value + 0x0010 + + REZ_FLAG_NO_COLLIDE_FAMILY + + tooltip + Object will not trigger collision events with other objects created by the same rezzer. + type + integer + value + 0x0040 + + REZ_FLAG_NO_COLLIDE_OWNER + + tooltip + Object will not trigger collision events with its owner. + type + integer + value + 0x0020 + + REZ_FLAG_PHANTOM + + tooltip + Make the object phantom on rez. + type + integer + value + 0x0004 + + REZ_FLAG_PHYSICAL + + tooltip + Make the object physical on rez. + type + integer + value + 0x0002 + + REZ_FLAG_TEMP + + tooltip + Flag the object as temp on rez. + type + integer + value + 0x0001 + + REZ_LOCK_AXES + + tooltip + Prevent the object from rotating around some axes. [vector locks] + type + integer + value + 11 + + REZ_OMEGA + + tooltip + Omega applied to the rezzed object. [vector axis, integer rel, float spin, float gain] + type + integer + value + 7 + + REZ_PARAM + + tooltip + Integer value to pass to the object as its rez parameter. [integer param] + type + integer + value + 0 + + REZ_PARAM_STRING + + tooltip + A string value to pass to the object as its rez parameter. [string param] + type + integer + value + 13 + + REZ_POS + + tooltip + Position at which to rez the new object. [vector position, integer rel, integer atroot] + type + integer + value + 2 + + REZ_ROT + + tooltip + Rotation applied to newly rezzed object. [rotation rot, integer rel] + type + integer + value + 3 + + REZ_SOUND + + tooltip + Sound attached to the rezzed object. [string name, float volume, integer loop] + type + integer + value + 9 + + REZ_SOUND_COLLIDE + + tooltip + Sound played by the object on a collision. [string name, float volume] + type + integer + value + 10 + + REZ_VEL + + tooltip + Initial velocity of rezzed object. [vector vel, integer rel, integer inherit] + type + integer + value + 4 + + ROTATE + + tooltip + Animate texture rotation. + type + integer + value + 0x20 + + SCALE + + tooltip + Animate the texture scale. + type + integer + value + 0x40 + + SCRIPTED + + tooltip + Scripted in-world objects. + type + integer + value + 0x8 + + SIM_STAT_ACTIVE_SCRIPT_COUNT + + tooltip + Number of active scripts. + type + integer + value + 12 + + SIM_STAT_AGENT_COUNT + + tooltip + Number of agents in region. + type + integer + value + 10 + + SIM_STAT_AGENT_MS + + tooltip + Time spent in 'agent' segment of simulation frame. + type + integer + value + 7 + + SIM_STAT_AGENT_UPDATES + + tooltip + Agent updates per second. + type + integer + value + 2 + + SIM_STAT_AI_MS + + tooltip + Time spent on AI step. + type + integer + value + 26 + + SIM_STAT_ASSET_DOWNLOADS + + tooltip + Pending asset download count. + type + integer + value + 15 + + SIM_STAT_ASSET_UPLOADS + + tooltip + Pending asset upload count. + type + integer + value + 16 + + SIM_STAT_CHILD_AGENT_COUNT + + tooltip + Number of child agents in region. + type + integer + value + 11 + + SIM_STAT_FRAME_MS + + tooltip + Total frame time. + type + integer + value + 3 + + SIM_STAT_IMAGE_MS + + tooltip + Time spent in 'image' segment of simulation frame. + type + integer + value + 8 + + SIM_STAT_IO_PUMP_MS + + tooltip + Pump IO time. + type + integer + value + 24 + + SIM_STAT_NET_MS + + tooltip + Time spent in 'network' segment of simulation frame. + type + integer + value + 4 + + SIM_STAT_OTHER_MS + + tooltip + Time spent in 'other' segment of simulation frame. + type + integer + value + 5 + + SIM_STAT_PACKETS_IN + + tooltip + Packets in per second. + type + integer + value + 13 + + SIM_STAT_PACKETS_OUT + + tooltip + Packets out per second. + type + integer + value + 14 + + SIM_STAT_PCT_CHARS_STEPPED + + tooltip + Returns the % of pathfinding characters skipped each frame, averaged over the last minute.\nThe returned value corresponds to the "Characters Updated" stat in the viewer's Statistics Bar. + type + integer + value + 0 + + SIM_STAT_PHYSICS_FPS + + tooltip + Physics simulation FPS. + type + integer + value + 1 + + SIM_STAT_PHYSICS_MS + + tooltip + Time spent in 'physics' segment of simulation frame. + type + integer + value + 6 + + SIM_STAT_PHYSICS_OTHER_MS + + tooltip + Physics other time. + type + integer + value + 20 + + SIM_STAT_PHYSICS_SHAPE_MS + + tooltip + Physics shape update time. + type + integer + value + 19 + + SIM_STAT_PHYSICS_STEP_MS + + tooltip + Physics step time. + type + integer + value + 18 + + SIM_STAT_SCRIPT_EPS + + tooltip + Script events per second. + type + integer + value + 21 + + SIM_STAT_SCRIPT_MS + + tooltip + Time spent in 'script' segment of simulation frame. + type + integer + value + 9 + + SIM_STAT_SCRIPT_RUN_PCT + + tooltip + Percent of scripts run during frame. + type + integer + value + 25 + + SIM_STAT_SLEEP_MS + + tooltip + Time spent sleeping. + type + integer + value + 23 + + SIM_STAT_SPARE_MS + + tooltip + Spare time left after frame. + type + integer + value + 22 + + SIM_STAT_UNACKED_BYTES + + tooltip + Total unacknowledged bytes. + type + integer + value + 17 + + SIT_FLAG_ALLOW_UNSIT + + tooltip + The prim allows a seated avatar to stand up. + type + integer + value + 0x0002 + + SIT_FLAG_NO_COLLIDE + + tooltip + The seated avatar's hit box is disabled when seated on this prim. + type + integer + value + 0x0010 + + SIT_FLAG_NO_DAMAGE + + tooltip + Damage will not be forwarded to an avatar seated on this prim. + type + integer + value + 0x0020 + + SIT_FLAG_SCRIPTED_ONLY + + tooltip + An avatar may not manually sit on this prim. + type + integer + value + 0x0004 + + SIT_FLAG_SIT_TARGET + + tooltip + The prim has an explicitly set sit target. + type + integer + value + 0x0001 + + SIT_INVALID_AGENT + + tooltip + Avatar ID did not specify a valid avatar. + type + integer + value + -4 + + SIT_INVALID_LINK + + tooltip + Link ID did not specify a valid prim in the linkset or resolved to multiple prims. + type + integer + value + -5 + + SIT_INVALID_OBJECT + + tooltip + Attempt to force an avatar to sit on an attachment or other invalid target. + type + integer + value + -7 + + SIT_NOT_EXPERIENCE + + tooltip + Attempt to force an avatar to sit outside an experience. + type + integer + value + -1 + + SIT_NO_ACCESS + + tooltip + Avatar does not have access to the parcel containing the target linkset of the forced sit. + type + integer + value + -6 + + SIT_NO_EXPERIENCE_PERMISSION + + tooltip + Avatar has not granted permission to force sits. + type + integer + value + -2 + + SIT_NO_SIT_TARGET + + tooltip + No available sit target in linkset for forced sit. + type + integer + value + -3 + + SKY_AMBIENT + + tooltip + The ambient color of the environment + type + integer + value + 0 + + SKY_BLUE + + tooltip + Blue settings for environment + type + integer + value + 22 + + SKY_CLOUDS + + tooltip + Settings controlling cloud density and configuration + type + integer + value + 2 + + SKY_CLOUD_TEXTURE + + tooltip + Texture ID used by clouds + type + integer + value + 19 + + SKY_DOME + + tooltip + Sky dome information. + type + integer + value + 4 + + SKY_GAMMA + + tooltip + The gamma value applied to the scene. + type + integer + value + 5 + + SKY_GLOW + + tooltip + Glow color applied to the sun and moon. + type + integer + value + 6 + + SKY_HAZE + + tooltip + Haze settings for environment + type + integer + value + 23 + + SKY_LIGHT + + tooltip + Miscellaneous lighting values. + type + integer + value + 8 + + SKY_MOON + + tooltip + Environmental moon details. + type + integer + value + 9 + + SKY_MOON_TEXTURE + + tooltip + Environmental moon texture. + type + integer + value + 20 + + SKY_PLANET + + tooltip + Planet information used in rendering the sky. + type + integer + value + 10 + + SKY_REFLECTION_PROBE_AMBIANCE + + tooltip + Settings the ambience of the reflection probe. + type + integer + value + 24 + + SKY_REFRACTION + + tooltip + Sky refraction parameters for rainbows and optical effects. + type + integer + value + 11 + + SKY_STAR_BRIGHTNESS + + tooltip + Brightness value for the stars. + type + integer + value + 13 + + SKY_SUN + + tooltip + Detailed sun information + type + integer + value + 14 + + SKY_SUN_TEXTURE + + tooltip + Environmental sun texture + type + integer + value + 21 + + SKY_TEXTURE_DEFAULTS + + tooltip + Is the environment using the default textures. + type + integer + value + 1 + + SKY_TRACKS + + tooltip + Track elevations for this region. + type + integer + value + 15 + + SMOOTH + + tooltip + Slide in the X direction, instead of playing separate frames. + type + integer + value + 0x10 + + SOUND_LOOP + + tooltip + Sound will loop until stopped. + type + integer + value + 0x01 + + SOUND_PLAY + + tooltip + Sound will play normally. + type + integer + value + 0x00 + + SOUND_SYNC + + tooltip + Sound will be synchronized with the nearest master. + type + integer + value + 0x04 + + SOUND_TRIGGER + + tooltip + Sound will be triggered at the prim's location and not attached. + type + integer + value + 0x02 + + SQRT2 + + tooltip + 1.41421356 - The square root of 2. + type + float + value + 1.41421356 + + STATUS_BLOCK_GRAB + + tooltip + Controls whether the object can be grabbed.\nA grab is the default action when in third person, and is available as the hand tool in build mode. This is useful for physical objects that you don't want other people to be able to trivially disturb. The default is FALSE + type + integer + value + 0x40 + + STATUS_BLOCK_GRAB_OBJECT + + tooltip + Prevent click-and-drag movement on all prims in the object. + type + integer + value + 0x400 + + STATUS_BOUNDS_ERROR + + tooltip + Argument(s) passed to function had a bounds error. + type + integer + value + 1002 + + STATUS_CAST_SHADOWS + + tooltip + + type + integer + value + 0x200 + + STATUS_DIE_AT_EDGE + + tooltip + Controls whether the object is returned to the owners inventory if it wanders off the edge of the world.\nIt is useful to set this status TRUE for things like bullets or rockets. The default is TRUE + type + integer + value + 0x80 + + STATUS_DIE_AT_NO_ENTRY + + tooltip + Controls whether the object dies if it attempts to enter a parcel that does not allow object entry or does not have enough capacity.\nIt is useful to set this status TRUE for things like bullets or rockets. The default is FALSE + type + integer + value + 0x800 + + STATUS_INTERNAL_ERROR + + tooltip + An internal error occurred. + type + integer + value + 1999 + + STATUS_MALFORMED_PARAMS + + tooltip + Function was called with malformed parameters. + type + integer + value + 1000 + + STATUS_NOT_FOUND + + tooltip + Object or other item was not found. + type + integer + value + 1003 + + STATUS_NOT_SUPPORTED + + tooltip + Feature not supported. + type + integer + value + 1004 + + STATUS_OK + + tooltip + Result of function call was a success. + type + integer + value + 0 + + STATUS_PHANTOM + + tooltip + Controls/indicates whether the object collides or not.\nSetting the value to TRUE makes the object non-colliding with all objects. It is a good idea to use this for most objects that move or rotate, but are non-physical. It is also useful for simulating volumetric lighting. The default is FALSE. + type + integer + value + 0x10 + + STATUS_PHYSICS + + tooltip + Controls/indicates whether the object moves physically.\nThis controls the same flag that the UI check-box for Physical controls. The default is FALSE. + type + integer + value + 0x1 + + STATUS_RETURN_AT_EDGE + + tooltip + + type + integer + value + 0x100 + + STATUS_ROTATE_X + + tooltip + + type + integer + value + 0x2 + + STATUS_ROTATE_Y + + tooltip + + type + integer + value + 0x4 + + STATUS_ROTATE_Z + + tooltip + + Controls/indicates whether the object can physically rotate around + the specific axis or not. This flag has no meaning + for non-physical objects. Set the value to FALSE + if you want to disable rotation around that axis. The + default is TRUE for a physical object. + A useful example to think about when visualizing + the effect is a sit-and-spin device. They spin around the + Z axis (up) but not around the X or Y axis. + + type + integer + value + 0x8 + + STATUS_SANDBOX + + tooltip + + Controls/indicates whether the object can cross region boundaries + and move more than 20 meters from its creation + point. The default if FALSE. + + type + integer + value + 0x20 + + STATUS_TYPE_MISMATCH + + tooltip + Argument(s) passed to function had a type mismatch. + type + integer + value + 1001 + + STATUS_WHITELIST_FAILED + + tooltip + Whitelist Failed. + type + integer + value + 2001 + + STRING_TRIM + + tooltip + + type + integer + value + 0x03 + + STRING_TRIM_HEAD + + tooltip + + type + integer + value + 0x01 + + STRING_TRIM_TAIL + + tooltip + + type + integer + value + 0x02 + + TARGETED_EMAIL_OBJECT_OWNER + + tooltip + Send email to the owner of the object + type + integer + value + 0x02 + + TARGETED_EMAIL_ROOT_CREATOR + + tooltip + Send email to the creator of the root object + type + integer + value + 0x01 + + TERRAIN_DETAIL_1 + + tooltip + + type + integer + value + 0 + + TERRAIN_DETAIL_2 + + tooltip + + type + integer + value + 1 + + TERRAIN_DETAIL_3 + + tooltip + + type + integer + value + 2 + + TERRAIN_DETAIL_4 + + tooltip + + type + integer + value + 3 + + TERRAIN_HEIGHT_RANGE_NE + + tooltip + + type + integer + value + 7 + + TERRAIN_HEIGHT_RANGE_NW + + tooltip + + type + integer + value + 6 + + TERRAIN_HEIGHT_RANGE_SE + + tooltip + + type + integer + value + 5 + + TERRAIN_HEIGHT_RANGE_SW + + tooltip + + type + integer + value + 4 + + TERRAIN_PBR_OFFSET_1 + + tooltip + + type + integer + value + 16 + + TERRAIN_PBR_OFFSET_2 + + tooltip + + type + integer + value + 17 + + TERRAIN_PBR_OFFSET_3 + + tooltip + + type + integer + value + 18 + + TERRAIN_PBR_OFFSET_4 + + tooltip + + type + integer + value + 19 + + TERRAIN_PBR_ROTATION_1 + + tooltip + + type + integer + value + 12 + + TERRAIN_PBR_ROTATION_2 + + tooltip + + type + integer + value + 13 + + TERRAIN_PBR_ROTATION_3 + + tooltip + + type + integer + value + 14 + + TERRAIN_PBR_ROTATION_4 + + tooltip + + type + integer + value + 15 + + TERRAIN_PBR_SCALE_1 + + tooltip + + type + integer + value + 8 + + TERRAIN_PBR_SCALE_2 + + tooltip + + type + integer + value + 9 + + TERRAIN_PBR_SCALE_3 + + tooltip + + type + integer + value + 10 + + TERRAIN_PBR_SCALE_4 + + tooltip + + type + integer + value + 11 + + TEXTURE_BLANK + + tooltip + + type + string + value + 5748decc-f629-461c-9a36-a35a221fe21f + + TEXTURE_DEFAULT + + tooltip + + type + string + value + 89556747-24cb-43ed-920b-47caed15465f + + TEXTURE_MEDIA + + tooltip + + type + string + value + 8b5fec65-8d8d-9dc5-cda8-8fdf2716e361 + + TEXTURE_PLYWOOD + + tooltip + + type + string + value + 89556747-24cb-43ed-920b-47caed15465f + + TEXTURE_TRANSPARENT + + tooltip + + type + string + value + 8dcd4a48-2d37-4909-9f78-f7a9eb4ef903 + + TOUCH_INVALID_FACE + + tooltip + + type + integer + value + -1 + + TOUCH_INVALID_TEXCOORD + + tooltip + + type + vector + value + <-1.0, -1.0, 0.0> + + TOUCH_INVALID_VECTOR + + tooltip + + type + vector + value + <0.0, 0.0, 0.0> + + TP_ROUTING_BLOCKED + + tooltip + Direct teleporting is blocked on this parcel. + type + integer + value + 0 + + TP_ROUTING_FREE + + tooltip + Teleports are unrestricted on this parcel. + type + integer + value + 2 + + TP_ROUTING_LANDINGP + + tooltip + Teleports are routed to a landing point if set on this parcel. + type + integer + value + 1 + + TRANSFER_BAD_OPTS + + tooltip + Invalid inventory options. + type + integer + value + -1 + + TRANSFER_BAD_ROOT + + tooltip + The root path specified in TRANSFER_DEST contained an invalid directory or was reduced to nothing. + type + integer + value + -5 + + TRANSFER_DEST + + tooltip + The root folder to transfer inventory into. + type + integer + value + 0 + + TRANSFER_FLAGS + + tooltip + Flags to control the behavior of inventory transfer. + type + integer + value + 1 + + TRANSFER_FLAG_COPY + + tooltip + Gives a copy of the object being transfered. Implies TRANSFER_FLAG_TAKE. + type + integer + value + 0x0004 + + TRANSFER_FLAG_RESERVED + + tooltip + Reserved for future expansion. + type + integer + value + 0x0001 + + TRANSFER_FLAG_TAKE + + tooltip + On a successful transfer, automatically takes the object into inventory. + type + integer + value + 0x0002 + + TRANSFER_NO_ATTACHMENT + + tooltip + Can not transfer ownership of an attached object. + type + integer + value + -7 + + TRANSFER_NO_ITEMS + + tooltip + No items in the inventory list are eligible for transfer. + type + integer + value + -4 + + TRANSFER_NO_PERMS + + tooltip + The object does not have transfer permissions. + type + integer + value + -6 + + TRANSFER_NO_TARGET + + tooltip + Could not find the receiver in the current region. + type + integer + value + -2 + + TRANSFER_OK + + tooltip + Inventory transfer offer was successfully made. + type + integer + value + 0 + + TRANSFER_THROTTLE + + tooltip + Inventory throttle hit. + type + integer + value + -3 + + TRAVERSAL_TYPE + + tooltip + One of TRAVERSAL_TYPE_FAST, TRAVERSAL_TYPE_SLOW, and TRAVERSAL_TYPE_NONE. + type + integer + value + 7 + + TRAVERSAL_TYPE_FAST + + tooltip + + type + integer + value + 1 + + TRAVERSAL_TYPE_NONE + + tooltip + + type + integer + value + 2 + + TRAVERSAL_TYPE_SLOW + + tooltip + + type + integer + value + 0 + + TRUE + + tooltip + An integer constant for boolean comparisons. Has the value '1'. + type + integer + value + 1 + + TWO_PI + + tooltip + 6.28318530 - The radians of a circle. + type + float + value + 6.28318530 + + TYPE_FLOAT + + tooltip + The list entry is a float. + type + integer + value + 2 + + TYPE_INTEGER + + tooltip + The list entry is an integer. + type + integer + value + 1 + + TYPE_INVALID + + tooltip + The list entry is invalid. + type + integer + value + 0 + + TYPE_KEY + + tooltip + The list entry is a key. + type + integer + value + 4 + + TYPE_ROTATION + + tooltip + The list entry is a rotation. + type + integer + value + 6 + + TYPE_STRING + + tooltip + The list entry is a string. + type + integer + value + 3 + + TYPE_VECTOR + + tooltip + The list entry is a vector. + type + integer + value + 5 + + URL_REQUEST_DENIED + + tooltip + + type + string + value + URL_REQUEST_DENIED + + URL_REQUEST_GRANTED + + tooltip + + type + string + value + URL_REQUEST_GRANTED + + VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY + + tooltip + A slider between minimum (0.0) and maximum (1.0) deflection of angular orientation. That is, its a simple scalar for modulating the strength of angular deflection such that the vehicles preferred axis of motion points toward its real velocity. + type + integer + value + 32 + + VEHICLE_ANGULAR_DEFLECTION_TIMESCALE + + tooltip + The time-scale for exponential success of linear deflection deflection. Its another way to specify the strength of the vehicles tendency to reorient itself so that its preferred axis of motion agrees with its true velocity. + type + integer + value + 33 + + VEHICLE_ANGULAR_FRICTION_TIMESCALE + + tooltip + + A vector of timescales for exponential decay of the vehicles angular velocity about its preferred axes of motion (at, left, up). + Range = [0.07, inf) seconds for each element of the vector. + + type + integer + value + 17 + + VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE + + tooltip + The timescale for exponential decay of the angular motors magnitude. + type + integer + value + 35 + + VEHICLE_ANGULAR_MOTOR_DIRECTION + + tooltip + The direction and magnitude (in preferred frame) of the vehicles angular motor.The vehicle will accelerate (or decelerate if necessary) to match its velocity to its motor. + type + integer + value + 19 + + VEHICLE_ANGULAR_MOTOR_TIMESCALE + + tooltip + The timescale for exponential approach to full angular motor velocity. + type + integer + value + 34 + + VEHICLE_BANKING_EFFICIENCY + + tooltip + A slider between anti (-1.0), none (0.0), and maxmum (1.0) banking strength. + type + integer + value + 38 + + VEHICLE_BANKING_MIX + + tooltip + A slider between static (0.0) and dynamic (1.0) banking. "Static" means the banking scales only with the angle of roll, whereas "dynamic" is a term that also scales with the vehicles linear speed. + type + integer + value + 39 + + VEHICLE_BANKING_TIMESCALE + + tooltip + The timescale for banking to exponentially approach its maximum effect. This is another way to scale the strength of the banking effect, however it affects the term that is proportional to the difference between what the banking behavior is trying to do, and what the vehicle is actually doing. + type + integer + value + 40 + + VEHICLE_BUOYANCY + + tooltip + A slider between minimum (0.0) and maximum anti-gravity (1.0). + type + integer + value + 27 + + VEHICLE_FLAG_BLOCK_INTERFERENCE + + tooltip + Prevent other scripts from pushing vehicle. + type + integer + value + 0x400 + + VEHICLE_FLAG_CAMERA_DECOUPLED + + tooltip + + type + integer + value + 0x200 + + VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT + + tooltip + Hover at global height. + type + integer + value + 0x10 + + VEHICLE_FLAG_HOVER_TERRAIN_ONLY + + tooltip + Ignore water height when hovering. + type + integer + value + 0x8 + + VEHICLE_FLAG_HOVER_UP_ONLY + + tooltip + Hover does not push down. Use this flag for hovering vehicles that should be able to jump above their hover height. + type + integer + value + 0x20 + + VEHICLE_FLAG_HOVER_WATER_ONLY + + tooltip + Ignore terrain height when hovering. + type + integer + value + 0x4 + + VEHICLE_FLAG_LIMIT_MOTOR_UP + + tooltip + Prevents ground vehicles from motoring into the sky. + type + integer + value + 0x40 + + VEHICLE_FLAG_LIMIT_ROLL_ONLY + + tooltip + For vehicles with vertical attractor that want to be able to climb/dive, for instance, aeroplanes that want to use the banking feature. + type + integer + value + 0x2 + + VEHICLE_FLAG_MOUSELOOK_BANK + + tooltip + + type + integer + value + 0x100 + + VEHICLE_FLAG_MOUSELOOK_STEER + + tooltip + + type + integer + value + 0x80 + + VEHICLE_FLAG_NO_DEFLECTION_UP + + tooltip + This flag prevents linear deflection parallel to world z-axis. This is useful for preventing ground vehicles with large linear deflection, like bumper cars, from climbing their linear deflection into the sky. + type + integer + value + 0x1 + + VEHICLE_FLAG_NO_FLY_UP + + deprecated + 1 + tooltip + Old, changed to VEHICLE_FLAG_NO_DEFLECTION_UP + type + integer + value + 0x1 + + VEHICLE_HOVER_EFFICIENCY + + tooltip + A slider between minimum (0.0 = bouncy) and maximum (1.0 = fast as possible) damped motion of the hover behavior. + type + integer + value + 25 + + VEHICLE_HOVER_HEIGHT + + tooltip + The height (above the terrain or water, or global) at which the vehicle will try to hover. + type + integer + value + 24 + + VEHICLE_HOVER_TIMESCALE + + tooltip + Period of time (in seconds) for the vehicle to achieve its hover height. + type + integer + value + 26 + + VEHICLE_LINEAR_DEFLECTION_EFFICIENCY + + tooltip + A slider between minimum (0.0) and maximum (1.0) deflection of linear velocity. That is, its a simple scalar for modulating the strength of linear deflection. + type + integer + value + 28 + + VEHICLE_LINEAR_DEFLECTION_TIMESCALE + + tooltip + The timescale for exponential success of linear deflection deflection. It is another way to specify how much time it takes for the vehicles linear velocity to be redirected to its preferred axis of motion. + type + integer + value + 29 + + VEHICLE_LINEAR_FRICTION_TIMESCALE + + tooltip + + A vector of timescales for exponential decay of the vehicles linear velocity along its preferred axes of motion (at, left, up). + Range = [0.07, inf) seconds for each element of the vector. + + type + integer + value + 16 + + VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE + + tooltip + The timescale for exponential decay of the linear motors magnitude. + type + integer + value + 31 + + VEHICLE_LINEAR_MOTOR_DIRECTION + + tooltip + + The direction and magnitude (in preferred frame) of the vehicles linear motor. The vehicle will accelerate (or decelerate if necessary) to match its velocity to its motor. + Range of magnitude = [0, 30] meters/second. + + type + integer + value + 18 + + VEHICLE_LINEAR_MOTOR_OFFSET + + tooltip + + type + integer + value + 20 + + VEHICLE_LINEAR_MOTOR_TIMESCALE + + tooltip + The timescale for exponential approach to full linear motor velocity. + type + integer + value + 30 + + VEHICLE_REFERENCE_FRAME + + tooltip + A rotation of the vehicles preferred axes of motion and orientation (at, left, up) with respect to the vehicles local frame (x, y, z). + type + integer + value + 44 + + VEHICLE_TYPE_AIRPLANE + + tooltip + Uses linear deflection for lift, no hover, and banking to turn.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_AIRPLANE + type + integer + value + 4 + + VEHICLE_TYPE_BALLOON + + tooltip + Hover, and friction, but no deflection.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_BALLOON + type + integer + value + 5 + + VEHICLE_TYPE_BOAT + + tooltip + Hovers over water with lots of friction and some anglar deflection.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_BOAT + type + integer + value + 3 + + VEHICLE_TYPE_CAR + + tooltip + Another vehicle that bounces along the ground but needs the motors to be driven from external controls or timer events.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_CAR + type + integer + value + 2 + + VEHICLE_TYPE_NONE + + tooltip + + type + integer + value + 0 + + VEHICLE_TYPE_SLED + + tooltip + Simple vehicle that bumps along the ground, and likes to move along its local x-axis.\nSee http://wiki.secondlife.com/wiki/VEHICLE_TYPE_SLED + type + integer + value + 1 + + VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY + + tooltip + A slider between minimum (0.0 = wobbly) and maximum (1.0 = firm as possible) stability of the vehicle to keep itself upright. + type + integer + value + 36 + + VEHICLE_VERTICAL_ATTRACTION_TIMESCALE + + tooltip + The period of wobble, or timescale for exponential approach, of the vehicle to rotate such that its preferred "up" axis is oriented along the worlds "up" axis. + type + integer + value + 37 + + VERTICAL + + tooltip + + type + integer + value + 0 + + WANDER_PAUSE_AT_WAYPOINTS + + tooltip + + type + integer + value + 0 + + WATER_BLUR_MULTIPLIER + + tooltip + Blur factor. + type + integer + value + 100 + + WATER_FOG + + tooltip + Fog properties when underwater. + type + integer + value + 101 + + WATER_FRESNEL + + tooltip + Fresnel scattering applied to the surface of the water. + type + integer + value + 102 + + WATER_NORMAL_SCALE + + tooltip + Scaling applied to the water normal map. + type + integer + value + 104 + + WATER_NORMAL_TEXTURE + + tooltip + Normal map used for environmental waves. + type + integer + value + 107 + + WATER_REFRACTION + + tooltip + Refraction factors when looking through the surface of the water. + type + integer + value + 105 + + WATER_TEXTURE_DEFAULTS + + tooltip + Is the environment using the default wave map. + type + integer + value + 103 + + WATER_WAVE_DIRECTION + + tooltip + Vectors for the directions of the waves. + type + integer + value + 106 + + XP_ERROR_EXPERIENCES_DISABLED + + tooltip + The region currently has experiences disabled. + type + integer + value + 2 + + XP_ERROR_EXPERIENCE_DISABLED + + tooltip + The experience owner has temporarily disabled the experience. + type + integer + value + 8 + + XP_ERROR_EXPERIENCE_SUSPENDED + + tooltip + The experience has been suspended by Linden Customer Support. + type + integer + value + 9 + + XP_ERROR_INVALID_EXPERIENCE + + tooltip + The script is associated with an experience that no longer exists. + type + integer + value + 7 + + XP_ERROR_INVALID_PARAMETERS + + tooltip + One of the string arguments was too big to fit in the key-value store. + type + integer + value + 3 + + XP_ERROR_KEY_NOT_FOUND + + tooltip + The requested key does not exist. + type + integer + value + 14 + + XP_ERROR_MATURITY_EXCEEDED + + tooltip + The content rating of the experience exceeds that of the region. + type + integer + value + 16 + + XP_ERROR_NONE + + tooltip + No error was detected. + type + integer + value + 0 + + XP_ERROR_NOT_FOUND + + tooltip + The sim was unable to verify the validity of the experience. Retrying after a short wait is advised. + type + integer + value + 6 + + XP_ERROR_NOT_PERMITTED + + tooltip + This experience is not allowed to run by the requested agent. + type + integer + value + 4 + + XP_ERROR_NOT_PERMITTED_LAND + + tooltip + This experience is not allowed to run on the current region. + type + integer + value + 17 + + XP_ERROR_NO_EXPERIENCE + + tooltip + This script is not associated with an experience. + type + integer + value + 5 + + XP_ERROR_QUOTA_EXCEEDED + + tooltip + An attempted write data to the key-value store failed due to the data quota being met. + type + integer + value + 11 + + XP_ERROR_REQUEST_PERM_TIMEOUT + + tooltip + Request timed out; permissions not modified. + type + integer + value + 18 + + XP_ERROR_RETRY_UPDATE + + tooltip + A checked update failed due to an out of date request. + type + integer + value + 15 + + XP_ERROR_STORAGE_EXCEPTION + + tooltip + Unable to communicate with the key-value store. + type + integer + value + 13 + + XP_ERROR_STORE_DISABLED + + tooltip + The key-value store is currently disabled on this region. + type + integer + value + 12 + + XP_ERROR_THROTTLED + + tooltip + The call failed due to too many recent calls. + type + integer + value + 1 + + XP_ERROR_UNKNOWN_ERROR + + tooltip + Other unknown error. + type + integer + value + 10 + + ZERO_ROTATION + + tooltip + + type + rotation + value + <0.0, 0.0, 0.0, 1.0> + + ZERO_VECTOR + + tooltip + + type + vector + value + <0.0, 0.0, 0.0> + + default + + tooltip + + All scripts must have a default state, which is the first state entered when the script starts. + If another state is defined before the default state, the compiler will report a syntax error. + + + + events + + at_rot_target + + arguments + + + TargetNumber + + tooltip + + type + integer + + + + TargetRotation + + tooltip + + type + rotation + + + + CurrentRotation + + tooltip + + type + rotation + + + + tooltip + This event is triggered when a script comes within a defined angle of a target rotation. The range and rotation, are set by a call to llRotTarget. + + at_target + + arguments + + + TargetNumber + + tooltip + + type + integer + + + + TargetPosition + + tooltip + + type + vector + + + + CurrentPosition + + tooltip + + type + vector + + + + tooltip + This event is triggered when the scripted object comes within a defined range of the target position, defined by the llTarget function call. + + attach + + arguments + + + AvatarID + + tooltip + + type + key + + + + tooltip + This event is triggered whenever an object is attached or detached from an avatar. If it is attached, the key of the avatar it is attached to is passed in, otherwise NULL_KEY is. + + changed + + arguments + + + Changed + + tooltip + + type + integer + + + + tooltip + Triggered when various events change the object. The change argument will be a bit-field of CHANGED_* constants. + + collision + + arguments + + + NumberOfCollisions + + tooltip + + type + integer + + + + tooltip + + This event is raised while another object, or avatar, is colliding with the object the script is attached to. + The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* functions. + + + collision_end + + arguments + + + NumberOfCollisions + + tooltip + + type + integer + + + + tooltip + + This event is raised when another object, or avatar, stops colliding with the object the script is attached to. + The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* library functions. + + + collision_start + + arguments + + + NumberOfCollisions + + tooltip + + type + integer + + + + tooltip + + This event is raised when another object, or avatar, starts colliding with the object the script is attached to. + The number of detected objects is passed to the script. Information on those objects may be gathered via the llDetected* library functions. + + + control + + arguments + + + AvatarID + + tooltip + + type + key + + + + Levels + + tooltip + + type + integer + + + + Edges + + tooltip + + type + integer + + + + tooltip + + Once a script has the ability to grab control inputs from the avatar, this event will be used to pass the commands into the script. + The levels and edges are bit-fields of control constants. + + + dataserver + + arguments + + + RequestID + + tooltip + + type + key + + + + Data + + tooltip + + type + string + + + + tooltip + + This event is triggered when the requested data is returned to the script. + Data may be requested by the llRequestAgentData, llRequestInventoryData, and llGetNotecardLine function calls, for example. + + + email + + arguments + + + Time + + tooltip + + type + string + + + + Address + + tooltip + + type + string + + + + Subject + + tooltip + + type + string + + + + Body + + tooltip + + type + string + + + + NumberRemaining + + tooltip + + type + integer + + + + tooltip + + This event is triggered when an email sent to this script arrives. + The number remaining tells how many more emails are known to be still pending. + + + experience_permissions + + arguments + + + agent_id + + tooltip + ID of the agent approving permission for the Experience. + type + key + + + + tooltip + Triggered when an agent has approved an experience permissions request. + + experience_permissions_denied + + arguments + + + agent_id + + tooltip + ID of the agent denying permission for the Experience. + type + key + + + + Reason + + tooltip + One of the XP_ERROR_... constants describing the reason why the Experience permissions were denied for the agent. + type + integer + + + + tooltip + Describes why the Experience permissions were denied for the agent. + + final_damage + + arguments + + + count + + tooltip + The number of damage events queued. + type + integer + + + + tooltip + Triggered as damage is applied to an avatar or task, after all on_damage events have been processed. + + game_control + + arguments + + + id + + tooltip + UUID of avatar supplying input + type + key + + + + buttons + + tooltip + 32-bit mask of buttons pressed + type + integer + + + + axes + + tooltip + Six float values in range [-1, 1] + type + list + + + + tooltip + This event is raised when game controller input changes. + + http_request + + arguments + + + HTTPRequestID + + tooltip + + type + key + + + + HTTPMethod + + tooltip + + type + string + + + + Body + + tooltip + + type + string + + + + tooltip + Triggered when task receives an HTTP request. + + http_response + + arguments + + + HTTPRequestID + + tooltip + + type + key + + + + Status + + tooltip + + type + integer + + + + Metadata + + tooltip + + type + list + + + + Body + + tooltip + + type + string + + + + tooltip + This event handler is invoked when an HTTP response is received for a pending llHTTPRequest request or if a pending request fails or times out. + + land_collision + + arguments + + + Position + + tooltip + + type + vector + + + + tooltip + This event is raised when the object the script is attached to is colliding with the ground. + + land_collision_end + + arguments + + + Position + + tooltip + + type + vector + + + + tooltip + This event is raised when the object the script is attached to stops colliding with the ground. + + land_collision_start + + arguments + + + Position + + tooltip + + type + vector + + + + tooltip + This event is raised when the object the script is attached to begins to collide with the ground. + + link_message + + arguments + + + SendersLink + + tooltip + + type + integer + + + + Value + + tooltip + + type + integer + + + + Text + + tooltip + + type + string + + + + ID + + tooltip + + type + key + + + + tooltip + Triggered when object receives a link message via llMessageLinked function call. + + linkset_data + + arguments + + + action + + tooltip + + type + integer + + + + name + + tooltip + + type + string + + + + value + + tooltip + + type + string + + + + tooltip + Triggered when a script modifies the linkset datastore. + + listen + + arguments + + + Channel + + tooltip + + type + integer + + + + Name + + tooltip + + type + string + + + + ID + + tooltip + + type + key + + + + Text + + tooltip + + type + string + + + + tooltip + + This event is raised whenever a chat message matching the constraints set in the llListen command is received. The name and ID of the speaker, as well as the message, are passed in as parameters. + Channel 0 is the public chat channel that all avatars see as chat text. Channels 1 through 2,147,483,648 are private channels that are not sent to avatars but other scripts can listen on those channels. + + + money + + arguments + + + Payer + + tooltip + + type + key + + + + Amount + + tooltip + + type + integer + + + + tooltip + This event is triggered when a resident has given an amount of Linden dollars to the object. + + moving_end + + arguments + + tooltip + Triggered whenever an object with this script stops moving. + + moving_start + + arguments + + tooltip + Triggered whenever an object with this script starts moving. + + no_sensor + + arguments + + tooltip + This event is raised when sensors are active, via the llSensor function call, but are not sensing anything. + + not_at_rot_target + + arguments + + tooltip + When a target is set via the llRotTarget function call, but the script is outside the specified angle this event is raised. + + not_at_target + + arguments + + tooltip + When a target is set via the llTarget library call, but the script is outside the specified range this event is raised. + + object_rez + + arguments + + + RezzedObjectsID + + tooltip + + type + key + + + + tooltip + Triggered when an object rezzes another object from its inventory via the llRezObject, or similar, functions. The id is the globally unique key for the object rezzed. + + on_damage + + arguments + + + count + + tooltip + The number of damage events queued. + type + integer + + + + tooltip + Triggered when an avatar or object receives damage. + + on_death + + arguments + + tooltip + Triggered when an avatar reaches 0 health. + + on_rez + + arguments + + + StartParameter + + tooltip + + type + integer + + + + tooltip + Triggered whenever an object is rezzed from inventory or by another object. The start parameter is passed in from the llRezObject call, or zero if from inventory. + + path_update + + arguments + + + Type + + tooltip + + type + integer + + + + Reserved + + tooltip + + type + list + + + + tooltip + This event is called to inform the script of changes within the object's path-finding status. + + remote_data + + arguments + + + EventType + + tooltip + + type + integer + + + + ChannelID + + tooltip + + type + key + + + + MessageID + + tooltip + + type + key + + + + Sender + + tooltip + + type + string + + + + IData + + tooltip + + type + integer + + + + SData + + tooltip + + type + string + + + + tooltip + This event is deprecated. + + run_time_permissions + + arguments + + + PermissionFlags + + tooltip + + type + integer + + + + tooltip + + Scripts need permission from either the owner or the avatar they wish to act on before they may perform certain functions, such as debiting money from their owners account, triggering an animation on an avatar, or capturing control inputs. The llRequestPermissions library function is used to request these permissions and the various permissions integer constants can be supplied. + The integer returned to this event handler contains the current set of permissions flags, so if permissions equal 0 then no permissions are set. + + + sensor + + arguments + + + NumberDetected + + tooltip + + type + integer + + + + tooltip + + This event is raised whenever objects matching the constraints of the llSensor command are detected. + The number of detected objects is passed to the script in the parameter. Information on those objects may be gathered via the llDetected* functions. + + + state_entry + + arguments + + tooltip + The state_entry event occurs whenever a new state is entered, including at program start, and is always the first event handled. + + state_exit + + arguments + + tooltip + The state_exit event occurs whenever the state command is used to transition to another state. It is handled before the new states state_entry event. + + timer + + arguments + + tooltip + This event is raised at regular intervals set by the llSetTimerEvent library function. + + touch + + arguments + + + NumberOfTouches + + tooltip + + type + integer + + + + tooltip + + This event is raised while a user is touching the object the script is attached to. + The number of touching objects is passed to the script in the parameter. + Information on those objects may be gathered via the llDetected* library functions. + + + touch_end + + arguments + + + NumberOfTouches + + tooltip + + type + integer + + + + tooltip + + This event is raised when a user stops touching the object the script is attached to. The number of touches is passed to the script in the parameter. + Information on those objects may be gathered via the llDetected* library functions. + + + touch_start + + arguments + + + NumberOfTouches + + tooltip + + type + integer + + + + tooltip + + This event is raised when a user first touches the object the script is attached to. The number of touches is passed to the script in the parameter. + Information on those objects may be gathered via the llDetected() library functions. + + + transaction_result + + arguments + + + RequestID + + tooltip + + type + key + + + + Success + + tooltip + + type + integer + + + + Message + + tooltip + + type + string + + + + tooltip + Triggered by llTransferMoney() function. + + + functions + + + assert + + arguments + + + value + + tooltip + The value to check for truthiness. + type + any + + + + message + + tooltip + Optional error message to display if the value is not truthy. + type + string? + + + + energy + 10 + return + any + sleep + 0 + tooltip + Checks if the value is truthy; if not, raises an error with the optional message. + + error + + arguments + + + obj + + tooltip + The error object to raise. + type + any + + + + level + + tooltip + Optional level to attribute the error to in the call stack. + type + number? + + + + energy + 10 + return + void + sleep + 0 + tooltip + Raises an error with the specified object and optional call stack level. + + gcinfo + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the total heap size in kilobytes. + + getfenv + + arguments + + + target + + tooltip + Optional function or stack index to get the environment table for. + type + (function | number)? + + + + energy + 10 + return + table + sleep + 0 + tooltip + Returns the environment table for the specified function or stack index. + + getmetatable + + arguments + + + obj + + tooltip + The object to get the metatable for. + type + any + + + + energy + 10 + return + table? + sleep + 0 + tooltip + Returns the metatable for the specified object. + + next + + arguments + + + t + + tooltip + The table to traverse. + type + table + + + + i + + tooltip + Optional key to start traversal after. + type + any? + + + + energy + 10 + return + (any, any)? + sleep + 0 + tooltip + Returns the next key-value pair in the table traversal order. + + newproxy + + arguments + + + mt + + tooltip + Optional boolean to create a modifiable metatable. + type + boolean? + + + + energy + 10 + return + userdata + sleep + 0 + tooltip + Creates a new untyped userdata object with an optional metatable. + + print + + arguments + + + args + + tooltip + Arguments to print to standard output. + type + ...any + + + + energy + 10 + return + void + sleep + 0 + tooltip + Prints all arguments to standard output using Tab as a separator. + + rawequal + + arguments + + + a + + tooltip + First object to compare. + type + any + + + + b + + tooltip + Second object to compare. + type + any + + + + energy + 10 + return + boolean + sleep + 0 + tooltip + Returns true if a and b have the same type and value. + + rawget + + arguments + + + t + + tooltip + The table to perform the lookup on. + type + table + + + + k + + tooltip + The key to look up in the table. + type + any + + + + energy + 10 + return + any? + sleep + 0 + tooltip + Performs a table lookup bypassing metatables. + + rawset + + arguments + + + t + + tooltip + The table to assign the value to. + type + table + + + + k + + tooltip + The key to assign the value to. + type + any + + + + v + + tooltip + The value to assign. + type + any + + + + energy + 10 + return + void + sleep + 0 + tooltip + Assigns a value to a table field bypassing metatables. + + select + + arguments + + + i + + tooltip + The index or '#' to count arguments. + type + string | number + + + + args + + tooltip + The arguments to select from. + type + ...any + + + + energy + 10 + return + any + sleep + 0 + tooltip + Returns a subset of arguments or the number of arguments. + + setfenv + + arguments + + + target + + tooltip + The function or stack index to set the environment for. + type + function | number + + + + env + + tooltip + The environment table to set. + type + table + + + + energy + 10 + return + void + sleep + 0 + tooltip + Changes the environment table for the specified function or stack index. + + setmetatable + + arguments + + + t + + tooltip + The table to set the metatable for. + type + table + + + + mt + + tooltip + The metatable to set. + type + table? + + + + energy + 10 + return + void + sleep + 0 + tooltip + Changes the metatable for the given table. + + tonumber + + arguments + + + s + + tooltip + The string to convert to a number. + type + string + + + + base + + tooltip + Optional base for the conversion. + type + number? + + + + energy + 10 + return + number? + sleep + 0 + tooltip + Converts the input string to a number in the specified base. + + tostring + + arguments + + + obj + + tooltip + The object to convert to a string. + type + any + + + + energy + 10 + return + string + sleep + 0 + tooltip + Converts the input object to a string. + + type + + arguments + + + obj + + tooltip + The object to get the type of. + type + any + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the type of the object as a string. + + typeof + + arguments + + + obj + + tooltip + The object to get the type of. + type + any + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the type of the object, including custom userdata types. + + ipairs + + arguments + + + t + + tooltip + The table to iterate over. + type + table + + + + energy + 10 + return + iterator + sleep + 0 + tooltip + Returns an iterator for numeric key-value pairs in the table. + + pairs + + arguments + + + t + + tooltip + The table to iterate over. + type + table + + + + energy + 10 + return + iterator + sleep + 0 + tooltip + Returns an iterator for all key-value pairs in the table. + + pcall + + arguments + + + f + + tooltip + A function to be called. + type + function + + + + args + + tooltip + Arguments to pass to the function. + type + variadic + + + + energy + 10 + return + boolean, variadic + sleep + 0 + tooltip + Calls function f with parameters args, returning success and function results or an error. + + xpcall + + arguments + + + f + + tooltip + A function to be called. + type + function + + + + e + + tooltip + Error handler function. + type + function + + + + args + + tooltip + Arguments to pass to the function. + type + variadic + + + + energy + 10 + return + boolean, variadic + sleep + 0 + tooltip + Calls function f with parameters args, handling errors with e if they occur. + + unpack + + arguments + + + a + + tooltip + Array from which to extract values. + type + array + + + + f + + tooltip + Starting index (optional, defaults to 1). + type + number + + + + t + + tooltip + Ending index (optional, defaults to #a). + type + number + + + + energy + 10 + return + variadic + sleep + 0 + tooltip + Returns values from an array in the specified index range. + + + math + + energy + -1.0 + tooltip + math namespace. + + math.abs + + arguments + + + n + + tooltip + A number. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the absolute value of n. + + math.acos + + arguments + + + n + + tooltip + A number in the range [-1, 1]. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the arc cosine of n in radians. + + math.asin + + arguments + + + n + + tooltip + A number in the range [-1, 1]. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the arc sine of n in radians. + + math.atan2 + + arguments + + + y + + tooltip + The y-coordinate. + type + number + + + + x + + tooltip + The x-coordinate. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the arc tangent of y/x in radians. + + math.atan + + arguments + + + n + + tooltip + A number. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the arc tangent of n in radians. + + math.ceil + + arguments + + + n + + tooltip + A number. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Rounds n upwards to the next integer boundary. + + math.cosh + + arguments + + + n + + tooltip + A number to compute the hyperbolic cosine of. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the hyperbolic cosine of n. + + math.cos + + arguments + + + n + + tooltip + An angle in radians. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the cosine of n. + + math.deg + + arguments + + + n + + tooltip + A value in radians. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Converts n from radians to degrees. + + math.exp + + arguments + + + n + + tooltip + A number to compute e^n. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the base-e exponent of n. + + math.floor + + arguments + + + n + + tooltip + A number to round down. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Rounds n down to the previous integer. + + math.fmod + + arguments + + + x + + tooltip + The dividend. + type + number + + + + y + + tooltip + The divisor. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the remainder of x modulo y, rounded towards zero. + + math.frexp + + arguments + + + n + + tooltip + A number to split into significand and exponent. + type + number + + + + energy + 10 + return + array + sleep + 0 + tooltip + Splits n into a significand and exponent. + + math.ldexp + + arguments + + + s + + tooltip + The significand. + type + number + + + + e + + tooltip + The exponent. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns s * 2^e. + + math.lerp + + arguments + + + a + + tooltip + Start value. + type + number + + + + b + + tooltip + End value. + type + number + + + + t + + tooltip + Interpolation factor. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Linearly interpolates between a and b using factor t. + + math.log10 + + arguments + + + n + + tooltip + A number to compute base-10 logarithm. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns base-10 logarithm of n. + + math.log + + arguments + + + n + + tooltip + A number to compute logarithm. + type + number + + + + base + + tooltip + Base of the logarithm (default is e). + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns logarithm of n in the given base. + + math.max + + arguments + + + list + + tooltip + A list of numbers to find the maximum from. + type + array + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the maximum value in the given list. + + math.min + + arguments + + + list + + tooltip + A list of numbers to find the minimum from. + type + array + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the minimum value in the given list. + + math.modf + + arguments + + + n + + tooltip + A number to split into integer and fractional parts. + type + number + + + + energy + 10 + return + array + sleep + 0 + tooltip + Returns the integer and fractional parts of n. + + math.pow + + arguments + + + x + + tooltip + Base value. + type + number + + + + y + + tooltip + Exponent value. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns x raised to the power of y. + + math.rad + + arguments + + + n + + tooltip + A value in degrees. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Converts n from degrees to radians. + + math.random + + arguments + + + min + + tooltip + Minimum value of the range (optional). + type + number + + + + max + + tooltip + Maximum value of the range (optional). + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns a random number within the given range. + + math.randomseed + + arguments + + + seed + + tooltip + Seed for the random number generator. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the seed for the random number generator. + + math.sinh + + arguments + + + n + + tooltip + A number to compute the hyperbolic sine of. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the hyperbolic sine of n. + + math.sin + + arguments + + + n + + tooltip + An angle in radians. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the sine of n. + + math.sqrt + + arguments + + + n + + tooltip + A number to compute the square root of. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the square root of n. + + math.tanh + + arguments + + + n + + tooltip + A number to compute the hyperbolic tangent of. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the hyperbolic tangent of n. + + math.tan + + arguments + + + n + + tooltip + An angle in radians. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the tangent of n. + + math.noise + + arguments + + + x + + tooltip + X coordinate for the noise function. + type + number + + + + y + + tooltip + Y coordinate for the noise function (optional). + type + number + + + + z + + tooltip + Z coordinate for the noise function (optional). + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns Perlin noise value for the point (x, y, z). + + math.clamp + + arguments + + + n + + tooltip + The value to be clamped. + type + number + + + + min + + tooltip + Minimum allowable value. + type + number + + + + max + + tooltip + Maximum allowable value. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns n clamped between min and max. + + math.sign + + arguments + + + n + + tooltip + A number to get the sign of. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns -1 if n is negative, 1 if positive, and 0 if zero. + + math.round + + arguments + + + n + + tooltip + A number to round to the nearest integer. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Rounds n to the nearest integer. + + + table + + energy + -1.0 + tooltip + table namespace. + + table.concat + + arguments + + + a + + tooltip + Array of strings. + type + array + + + + sep + + tooltip + Separator string. + type + string + + + + f + + tooltip + Starting index. + type + integer + + + + t + + tooltip + Ending index. + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Concatenates elements of an array with an optional separator. + + table.foreach + + arguments + + + t + + tooltip + Table to iterate over. + type + table + + + + f + + tooltip + Function applied to each key-value pair. + type + function + + + + energy + 10 + return + various + sleep + 0 + tooltip + Iterates over all key-value pairs in a table. + + table.getn + + arguments + + + t + + tooltip + Table whose length is determined. + type + table + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of elements in a table. + + table.maxn + + arguments + + + t + + tooltip + Table to search for the maximum numeric key. + type + table + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the highest numeric key in a table. + + table.insert + + arguments + + + t + + tooltip + Table to insert into. + type + table + + + + i + + tooltip + Position to insert at. + type + integer + + + + v + + tooltip + Value to insert. + type + various + + + + energy + 10 + return + void + sleep + 0 + tooltip + Inserts a value at a specific index in a table. + + table.remove + + arguments + + + t + + tooltip + Table to remove from. + type + table + + + + i + + tooltip + Position to remove. + type + integer + + + + energy + 10 + return + various + sleep + 0 + tooltip + Removes an element from a table at a given index. + + table.sort + + arguments + + + t + + tooltip + Table to be sorted. + type + table + + + + f + + tooltip + Comparison function. + type + function + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sorts a table in ascending order. + + table.pack + + arguments + + + args + + tooltip + Variable arguments. + type + varargs + + + + energy + 10 + return + table + sleep + 0 + tooltip + Packs multiple arguments into a table. + + table.unpack + + arguments + + + a + + tooltip + Table to unpack. + type + table + + + + f + + tooltip + Starting index. + type + integer + + + + t + + tooltip + Ending index. + type + integer + + + + energy + 10 + return + varargs + sleep + 0 + tooltip + Returns unpacked values from a table within a specified range. + + table.move + + arguments + + + a + + tooltip + Source table. + type + table + + + + f + + tooltip + Starting index. + type + integer + + + + t + + tooltip + Ending index. + type + integer + + + + d + + tooltip + Destination index. + type + integer + + + + tt + + tooltip + Optional target table. + type + table + + + + energy + 10 + return + table + sleep + 0 + tooltip + Moves elements from one table to another or within the same table. + + table.create + + arguments + + + n + + tooltip + Number of elements. + type + integer + + + + v + + tooltip + Value to prefill elements with. + type + various + + + + energy + 10 + return + table + sleep + 0 + tooltip + Creates a table with preallocated elements. + + table.find + + arguments + + + t + + tooltip + Table to search in. + type + table + + + + v + + tooltip + Value to find. + type + various + + + + init + + tooltip + Starting index for search. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Finds the first occurrence of a value in a table and returns its index. + + table.clear + + arguments + + + t + + tooltip + Table to clear. + type + table + + + + energy + 10 + return + void + sleep + 0 + tooltip + Clears all elements from a table while keeping its capacity. + + table.freeze + + arguments + + + t + + tooltip + Table to freeze. + type + table + + + + energy + 10 + return + table + sleep + 0 + tooltip + Freezes a table, preventing modifications. + + table.isfrozen + + arguments + + + t + + tooltip + Table to check. + type + table + + + + energy + 10 + return + boolean + sleep + 0 + tooltip + Returns true if a table is frozen. + + table.clone + + arguments + + + t + + tooltip + Table to clone. + type + table + + + + energy + 10 + return + table + sleep + 0 + tooltip + Creates a shallow copy of a table. + + + string + + energy + -1.0 + tooltip + string namespace. + + string.byte + + arguments + + + s + + tooltip + Input string. + type + string + + + + f + + tooltip + Starting index (optional). + type + number + + + + t + + tooltip + Ending index (optional). + type + number + + + + energy + 10 + return + number... + sleep + 0 + tooltip + Returns the numeric code of every byte in the input string within the given range. + + string.char + + arguments + + + args + + tooltip + Byte values to convert to string. + type + number... + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string containing characters for the given byte values. + + string.find + + arguments + + + s + + tooltip + Input string. + type + string + + + + p + + tooltip + Pattern to search for. + type + string + + + + init + + tooltip + Starting position (optional). + type + number + + + + plain + + tooltip + Perform raw search (optional). + type + boolean + + + + energy + 10 + return + number?, number?, string... + sleep + 0 + tooltip + Finds an instance of the pattern in the string. + + string.format + + arguments + + + s + + tooltip + Format string. + type + string + + + + args + + tooltip + Values to format. + type + any... + + + + energy + 10 + return + string + sleep + 0 + tooltip + Formats input values into a string using printf-style format specifiers. + + string.len + + arguments + + + s + + tooltip + Input string. + type + string + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the number of bytes in the string. + + string.lower + + arguments + + + s + + tooltip + Input string. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a lowercase version of the input string. + + string.upper + + arguments + + + s + + tooltip + Input string. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns an uppercase version of the input string. + + string.match + + arguments + + + s + + tooltip + Input string. + type + string + + + + p + + tooltip + Pattern to match. + type + string + + + + init + + tooltip + Starting position (optional). + type + number + + + + energy + 10 + return + string... + sleep + 0 + tooltip + Finds and returns matches for a pattern in the input string. + + string.rep + + arguments + + + s + + tooltip + Input string. + type + string + + + + n + + tooltip + Number of times to repeat the string. + type + number + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the input string repeated a given number of times. + + string.reverse + + arguments + + + s + + tooltip + Input string. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the input string with bytes in reverse order. + + string.sub + + arguments + + + s + + tooltip + Input string. + type + string + + + + f + + tooltip + Start index. + type + number + + + + t + + tooltip + End index (optional). + type + number + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a substring from the given range. + + string.gsub + + arguments + + + s + + tooltip + Input string. + type + string + + + + p + + tooltip + Pattern to replace. + type + string + + + + f + + tooltip + Replacement string, function, or table. + type + function | table | string + + + + maxs + + tooltip + Maximum replacements (optional). + type + number + + + + energy + 10 + return + string, number + sleep + 0 + tooltip + Performs pattern-based substitution in a string. + + string.pack + + arguments + + + f + + tooltip + Pack format string. + type + string + + + + args + + tooltip + Values to encode. + type + any... + + + + energy + 10 + return + string + sleep + 0 + tooltip + Packs values into a binary string. + + string.unpack + + arguments + + + f + + tooltip + Pack format string. + type + string + + + + s + + tooltip + Encoded string. + type + string + + + + energy + 10 + return + any... + sleep + 0 + tooltip + Decodes a binary string using a pack format. + + + coroutine + + energy + -1.0 + tooltip + coroutine namespace. + + coroutine.create + + arguments + + + f + + tooltip + A function to be executed by the new coroutine. + type + function + + + + energy + 10 + return + thread + sleep + 0 + tooltip + Returns a new coroutine that, when resumed, will run function f. + + coroutine.running + + arguments + + energy + 10 + return + thread? + sleep + 0 + tooltip + Returns the currently running coroutine, or nil if running in the main coroutine. + + coroutine.status + + arguments + + + co + + tooltip + The coroutine to check status of. + type + thread + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the status of the coroutine: "running", "suspended", "normal", or "dead". + + coroutine.wrap + + arguments + + + f + + tooltip + A function to execute in a coroutine. + type + function + + + + energy + 10 + return + function + sleep + 0 + tooltip + Creates a coroutine and returns a function that resumes it. + + coroutine.yield + + arguments + + + args + + tooltip + Values to pass to the resuming code. + type + variadic + + + + energy + 10 + return + variadic + sleep + 0 + tooltip + Yields the current coroutine, passing arguments to the resuming code. + + coroutine.isyieldable + + arguments + + energy + 10 + return + boolean + sleep + 0 + tooltip + Returns true if the coroutine can yield. + + coroutine.resume + + arguments + + + co + + tooltip + The coroutine to resume. + type + thread + + + + args + + tooltip + Arguments to pass to the coroutine. + type + variadic + + + + energy + 10 + return + (boolean, variadic) + sleep + 0 + tooltip + Resumes a coroutine, returning true and results if successful, or false and an error. + + coroutine.close + + arguments + + + co + + tooltip + The coroutine to close. + type + thread + + + + energy + 10 + return + (boolean, any?) + sleep + 0 + tooltip + Closes a coroutine, returning true if successful or false and an error. + + + bit32 + + energy + -1.0 + tooltip + bit32 library functions. + + bit32.arshift + + arguments + + + n + + tooltip + Number to shift. + type + number + + + + i + + tooltip + Number of bits to shift. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Shifts n by i bits to the right. If i is negative, a left shift is performed. + + bit32.band + + arguments + + + args + + tooltip + Numbers to perform bitwise AND on. + type + array + + + + energy + 10 + return + number + sleep + 0 + tooltip + Performs a bitwise AND operation on input numbers. + + bit32.bnot + + arguments + + + n + + tooltip + Number to negate. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the bitwise negation of the input number. + + utf8 + + energy + -1.0 + tooltip + UTF-8 library functions. + + utf8.offset + + arguments + + + s + + tooltip + Input string. + type + string + + + + n + + tooltip + Character position. + type + number + + + + i + + tooltip + Starting position (optional). + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the byte offset of the nth Unicode codepoint in string s. + + utf8.char + + arguments + + + args + + tooltip + Unicode codepoints. + type + array + + + + energy + 10 + return + string + sleep + 0 + tooltip + Creates a string from Unicode codepoints. + + utf8.codepoint + + arguments + + + s + + tooltip + Input string. + type + string + + + + i + + tooltip + Starting position (optional). + type + number + + + + j + + tooltip + Ending position (optional). + type + number + + + + energy + 10 + return + array + sleep + 0 + tooltip + Returns the Unicode codepoints in the specified range of string s. + + utf8.len + + arguments + + + s + + tooltip + Input string. + type + string + + + + i + + tooltip + Starting position (optional). + type + number + + + + j + + tooltip + Ending position (optional). + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the number of Unicode codepoints in the specified range of string s. + + utf8.codes + + arguments + + + s + + tooltip + Input string. + type + string + + + + energy + 10 + return + iterator + sleep + 0 + tooltip + Returns an iterator that produces the byte offset and Unicode codepoint for each character in string s. + + + os + + energy + -1.0 + tooltip + os namespace. + + os.clock + + arguments + + energy + 10 + return + number + sleep + 0 + tooltip + Returns a high-precision timestamp in seconds for measuring durations. + + os.date + + arguments + + + s + + tooltip + Optional format string for the date representation. + type + string + + + + t + + tooltip + Optional timestamp to format; defaults to the current time. + type + number + + + + energy + 10 + return + table|string + sleep + 0 + tooltip + Returns a table or string representation of the time based on the provided format. + + os.difftime + + arguments + + + a + + tooltip + First timestamp value. + type + number + + + + b + + tooltip + Second timestamp value. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the difference in seconds between two timestamps. + + os.time + + arguments + + + t + + tooltip + Optional table with date/time fields; returns the corresponding Unix timestamp. + type + table + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the current Unix timestamp or the timestamp of the given date. + + + debug + + energy + -1.0 + tooltip + debug namespace. + + debug.info + + arguments + + + co + + tooltip + Optional thread or function reference. + type + thread|function|number + + + + level + + tooltip + Stack level or function reference for inspection. + type + number + + + + s + + tooltip + String specifying requested information. + type + string + + + + energy + 10 + return + any + sleep + 0 + tooltip + Returns information about a stack frame or function based on specified format. + + debug.traceback + + arguments + + + co + + tooltip + Optional thread reference for traceback. + type + thread + + + + msg + + tooltip + Optional message prepended to the traceback. + type + string + + + + level + + tooltip + Optional stack level to start traceback. + type + number + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a human-readable call stack starting from the specified level. + + debug.getinfo + + arguments + + + thread + + tooltip + Optional thread whose stack frame is being inspected. + type + thread + + + + function + + tooltip + Function reference or stack level number. + type + function|number + + + + what + + tooltip + String specifying which fields to retrieve. + type + string + + + + energy + 10 + return + table + sleep + 0 + tooltip + Returns a table containing debug information about a function or stack frame. + + debug.getlocal + + arguments + + + level + + tooltip + Stack level number. + type + number + + + + index + + tooltip + Index of the local variable. + type + number + + + + energy + 10 + return + string|any + sleep + 0 + tooltip + Returns the name and value of a local variable at the specified stack level. + + debug.setlocal + + arguments + + + level + + tooltip + Stack level number. + type + number + + + + index + + tooltip + Index of the local variable. + type + number + + + + value + + tooltip + New value for the local variable. + type + any + + + + energy + 10 + return + boolean + sleep + 0 + tooltip + Sets the value of a local variable at the specified stack level. + + debug.getupvalue + + arguments + + + function + + tooltip + Function whose upvalues are being retrieved. + type + function + + + + index + + tooltip + Index of the upvalue. + type + number + + + + energy + 10 + return + string|any + sleep + 0 + tooltip + Returns the name and value of an upvalue for a given function. + + debug.setupvalue + + arguments + + + function + + tooltip + Function whose upvalues are being modified. + type + function + + + + index + + tooltip + Index of the upvalue. + type + number + + + + value + + tooltip + New value for the upvalue. + type + any + + + + energy + 10 + return + string + sleep + 0 + tooltip + Sets the value of an upvalue for a given function. + + debug.getmetatable + + arguments + + + value + + tooltip + Value whose metatable is retrieved. + type + any + + + + energy + 10 + return + table|nil + sleep + 0 + tooltip + Returns the metatable of the given value, if any. + + debug.setmetatable + + arguments + + + value + + tooltip + Value whose metatable is to be set. + type + any + + + + metatable + + tooltip + Table to be set as the new metatable. + type + table|nil + + + + energy + 10 + return + any + sleep + 0 + tooltip + Sets the metatable for a given value. + + + buffer + + energy + -1.0 + tooltip + buffer namespace. + + buffer.create + + arguments + + + size + + tooltip + Size of the buffer to create. + type + number + + + + energy + 10 + return + buffer + sleep + 0 + tooltip + Creates a buffer of the requested size with all bytes initialized to 0. + + buffer.fromstring + + arguments + + + str + + tooltip + String to initialize the buffer with. + type + string + + + + energy + 10 + return + buffer + sleep + 0 + tooltip + Creates a buffer initialized to the contents of the string. + + buffer.tostring + + arguments + + + b + + tooltip + Buffer to convert to a string. + type + buffer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the buffer data as a string. + + buffer.len + + arguments + + + b + + tooltip + Buffer to get the size of. + type + buffer + + + + energy + 10 + return + number + sleep + 0 + tooltip + Returns the size of the buffer in bytes. + + buffer.readi8 + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to read from. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Reads a signed 8-bit integer from the buffer at the given offset. + + buffer.writei8 + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + Value to write. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes a signed 8-bit integer to the buffer at the given offset. + + buffer.readstring + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to start reading. + type + number + + + + count + + tooltip + Number of bytes to read. + type + number + + + + energy + 10 + return + string + sleep + 0 + tooltip + Reads a string of the given length from the buffer at the specified offset. + + buffer.copy + + arguments + + + target + + tooltip + Target buffer to copy into. + type + buffer + + + + targetOffset + + tooltip + Offset in target buffer. + type + number + + + + source + + tooltip + Source buffer to copy from. + type + buffer + + + + sourceOffset + + tooltip + Offset in source buffer (optional). + type + number + + + + count + + tooltip + Number of bytes to copy (optional). + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Copies bytes from the source buffer into the target buffer. + + buffer.fill + + arguments + + + b + + tooltip + Buffer to fill. + type + buffer + + + + offset + + tooltip + Byte offset to start filling. + type + number + + + + value + + tooltip + Value to fill with. + type + number + + + + count + + tooltip + Number of bytes to fill (optional). + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Fills the buffer with the specified value starting at the given offset. + + buffer.readu8 + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to read from. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Reads an unsigned 8-bit integer from the buffer at the given offset. + + buffer.writeu8 + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + Value to write. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes an unsigned 8-bit integer to the buffer at the given offset. + + buffer.readi16 + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to read from. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Reads a signed 16-bit integer from the buffer at the given offset. + + buffer.writei16 + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + Value to write. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes a signed 16-bit integer to the buffer at the given offset. + + buffer.readf32 + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to read from. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Reads a 32-bit floating-point number from the buffer at the given offset. + + buffer.writef32 + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + Value to write. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes a 32-bit floating-point number to the buffer at the given offset. + + buffer.readf64 + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to read from. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Reads a 64-bit floating-point number from the buffer at the given offset. + + buffer.writef64 + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + Value to write. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes a 64-bit floating-point number to the buffer at the given offset. + + buffer.readu16 + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to read from. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Reads an unsigned 16-bit integer from the buffer at the given offset. + + buffer.writeu16 + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + Value to write. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes an unsigned 16-bit integer to the buffer at the given offset. + + buffer.readi32 + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to read from. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Reads a signed 32-bit integer from the buffer at the given offset. + + buffer.writei32 + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + Value to write. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes a signed 32-bit integer to the buffer at the given offset. + + buffer.readu32 + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to read from. + type + number + + + + energy + 10 + return + number + sleep + 0 + tooltip + Reads an unsigned 32-bit integer from the buffer at the given offset. + + buffer.writeu32 + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + Value to write. + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes an unsigned 32-bit integer to the buffer at the given offset. + + buffer.readstring + + arguments + + + b + + tooltip + Buffer to read from. + type + buffer + + + + offset + + tooltip + Byte offset to start reading. + type + number + + + + count + + tooltip + Number of bytes to read. + type + number + + + + energy + 10 + return + string + sleep + 0 + tooltip + Reads a string of the given length from the buffer at the specified offset. + + buffer.writestring + + arguments + + + b + + tooltip + Buffer to write to. + type + buffer + + + + offset + + tooltip + Byte offset to write at. + type + number + + + + value + + tooltip + String to write. + type + string + + + + count + + tooltip + Number of bytes to write (optional). + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Writes data from a string into the buffer at the specified offset. + + buffer.copy + + arguments + + + target + + tooltip + Target buffer to copy into. + type + buffer + + + + targetOffset + + tooltip + Offset in target buffer. + type + number + + + + source + + tooltip + Source buffer to copy from. + type + buffer + + + + sourceOffset + + tooltip + Offset in source buffer (optional). + type + number + + + + count + + tooltip + Number of bytes to copy (optional). + type + number + + + + energy + 10 + return + void + sleep + 0 + tooltip + Copies bytes from the source buffer into the target buffer. + + + vector + + energy + -1.0 + tooltip + vector namespace. + + vector.zero + + energy + 10 + return + vector + sleep + 0 + tooltip + Constant vector with all components set to 0. + + vector.one + + energy + 10 + return + vector + sleep + 0 + tooltip + Constant vector with all components set to 1. + + vector.create + + arguments + + + x + + tooltip + X component of the vector. + type + number + + + + y + + tooltip + Y component of the vector. + type + number + + + + z + + tooltip + Z component of the vector. + type + number + + + + w + + tooltip + W component of the vector (optional, defaults to 0 in 4-wide mode). + type + number + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Creates a new vector with the given component values. + + vector.magnitude + + arguments + + + vec + + tooltip + Input vector. + type + vector + + + + energy + 10 + return + number + sleep + 0 + tooltip + Calculates the magnitude of a given vector. + + vector.normalize + + arguments + + + vec + + tooltip + Input vector. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Computes the unit vector of a given vector. + + vector.cross + + arguments + + + vec1 + + tooltip + First input vector. + type + vector + + + + vec2 + + tooltip + Second input vector. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Computes the cross product of two vectors. + + vector.dot + + arguments + + + vec1 + + tooltip + First input vector. + type + vector + + + + vec2 + + tooltip + Second input vector. + type + vector + + + + energy + 10 + return + number + sleep + 0 + tooltip + Computes the dot product of two vectors. + + vector.angle + + arguments + + + vec1 + + tooltip + First input vector. + type + vector + + + + vec2 + + tooltip + Second input vector. + type + vector + + + + axis + + tooltip + Axis to determine the sign of the angle (optional). + type + vector + + + + energy + 10 + return + number + sleep + 0 + tooltip + Computes the angle between two vectors in radians. + + vector.floor + + arguments + + + vec + + tooltip + Input vector. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Applies math.floor to each component of the vector. + + vector.ceil + + arguments + + + vec + + tooltip + Input vector. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Applies math.ceil to each component of the vector. + + vector.abs + + arguments + + + vec + + tooltip + Input vector. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Applies math.abs to each component of the vector. + + vector.sign + + arguments + + + vec + + tooltip + Input vector. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Applies math.sign to each component of the vector. + + vector.clamp + + arguments + + + vec + + tooltip + Input vector to be clamped. + type + vector + + + + min + + tooltip + Minimum vector value. + type + vector + + + + max + + tooltip + Maximum vector value. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Clamps each component of the vector between min and max values. + + vector.max + + arguments + + + vectors + + tooltip + Multiple input vectors. + type + array of vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Computes the component-wise maximum of multiple vectors. + + vector.min + + arguments + + + vectors + + tooltip + Multiple input vectors. + type + array of vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Computes the component-wise minimum of multiple vectors. + + ll + + + energy + -1.0 + tooltip + ll namespace. + + ll.Abs + + arguments + + + Value + + tooltip + An integer value. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the absolute (positive) version of Value. + + ll.Acos + + arguments + + + Value + + tooltip + A floating-point value. + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the arc-cosine of Value, in radians. + + ll.AddToLandBanList + + arguments + + + ID + + tooltip + Agent UUID to add to ban-list. + type + key + + + + Hours + + tooltip + Period, in hours, to ban the avatar for. + type + float + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Add avatar ID to the parcel ban list for the specified number of Hours.\nA value of 0 for Hours will add the agent indefinitely.\nThe smallest value that Hours will accept is 0.01; anything smaller will be seen as 0.\nWhen values that small are used, it seems the function bans in approximately 30 second increments (Probably 36 second increments, as 0.01 of an hour is 36 seconds).\nResidents teleporting to a parcel where they are banned will be redirected to a neighbouring parcel. + + ll.AddToLandPassList + + arguments + + + ID + + tooltip + Agent UUID to add to pass-list. + type + key + + + + Hours + + tooltip + Period, in hours, to allow the avatar for. + type + float + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Add avatar ID to the land pass list, for a duration of Hours. + + ll.AdjustDamage + + arguments + + + Number + + tooltip + Damage event index to modify. + type + integer + + + + Damage + + tooltip + New damage amount to apply on this event. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Changes the amount of damage to be delivered by this damage event. + + ll.AdjustSoundVolume + + arguments + + + Volume + + tooltip + The volume to set. + type + float + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Adjusts the volume (0.0 - 1.0) of the currently playing attached sound.\nThis function has no effect on sounds started with llTriggerSound. + + ll.AgentInExperience + + arguments + + + AgentID + + tooltip + + type + key + + + + energy + 10 + return + integer + sleep + 0 + tooltip + + Returns TRUE if the agent is in the Experience and the Experience can run in the current location. + + + ll.AllowInventoryDrop + + arguments + + + Flag + + tooltip + Boolean, If TRUE allows anyone to drop inventory on prim, FALSE revokes. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + If Flag == TRUE, users without object modify permissions can still drop inventory items into the object. + + ll.AngleBetween + + arguments + + + Rot1 + + tooltip + First rotation. + type + rotation + + + + Rot2 + + tooltip + Second rotation. + type + rotation + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the angle, in radians, between rotations Rot1 and Rot2. + + ll.ApplyImpulse + + arguments + + + Force + + tooltip + Amount of impulse force to apply. + type + vector + + + + Local + + tooltip + Boolean, if TRUE, force is treated as a local directional vector instead of region directional vector. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Applies impulse to the object.\nIf Local == TRUE, apply the Force in local coordinates; otherwise, apply the Force in global coordinates.\nThis function only works on physical objects. + + ll.ApplyRotationalImpulse + + arguments + + + Force + + tooltip + Amount of impulse force to apply. + type + vector + + + + Local + + tooltip + Boolean, if TRUE, uses local axis, if FALSE, uses region axis. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Applies rotational impulse to the object.\nIf Local == TRUE, apply the Force in local coordinates; otherwise, apply the Force in global coordinates.\nThis function only works on physical objects. + + ll.Asin + + arguments + + + Value + + tooltip + A floating-point value. + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the arc-sine, in radians, of Value. + + ll.Atan2 + + arguments + + + y + + tooltip + A floating-point value. + type + float + + + + x + + tooltip + A floating-point value. + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the arc-tangent2 of y, x. + + ll.AttachToAvatar + + arguments + + + AttachmentPoint + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Attach to avatar at point AttachmentPoint.\nRequires the PERMISSION_ATTACH runtime permission. + + ll.AttachToAvatarTemp + + arguments + + + AttachPoint + + tooltip + Valid attachment point or ATTACH_* constant. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Follows the same convention as llAttachToAvatar, with the exception that the object will not create new inventory for the user, and will disappear on detach or disconnect. + + ll.AvatarOnLinkSitTarget + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + If an avatar is sitting on the link's sit target, return the avatar's key, NULL_KEY otherwise.\nReturns a key that is the UUID of the user seated on the specified link's prim. + + ll.AvatarOnSitTarget + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + If an avatar is seated on the sit target, returns the avatar's key, otherwise NULL_KEY.\nThis only will detect avatars sitting on sit targets defined with llSitTarget. + + ll.Axes2Rot + + arguments + + + Forward + + tooltip + Forward/Back part of rotation. + type + vector + + + + Left + + tooltip + Left/Right part of rotation. + type + vector + + + + Up + + tooltip + Up/Down part of rotation. + type + vector + + + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation represented by coordinate axes Forward, Left, and Up. + + ll.AxisAngle2Rot + + arguments + + + Axis + + tooltip + Axis. + type + vector + + + + Angle + + tooltip + Angle in radians. + type + float + + + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation that is a generated Angle about Axis. + + ll.Base64ToInteger + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns an integer that is the Text, Base64 decoded as a big endian integer.\nReturns zero if Text is longer then 8 characters. If Text contains fewer then 6 characters, the return value is unpredictable. + + ll.Base64ToString + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Converts a Base64 string to a conventional string.\nIf the conversion creates any unprintable characters, they are converted to question marks. + + ll.BreakAllLinks + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + De-links all prims in the link set (requires permission PERMISSION_CHANGE_LINKS be set). + + ll.BreakLink + + arguments + + + LinkNumber + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + De-links the prim with the given link number (requires permission PERMISSION_CHANGE_LINKS be set). + + ll.CSV2List + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + list + sleep + 0 + tooltip + Create a list from a string of comma separated values specified in Text. + + ll.CastRay + + arguments + + + Start + + tooltip + + type + vector + + + + End + + tooltip + + type + vector + + + + Options + + tooltip + + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Casts a ray into the physics world from 'start' to 'end' and returns data according to details in Options.\nReports collision data for intersections with objects.\nReturn value: [UUID_1, {link_number_1}, hit_position_1, {hit_normal_1}, UUID_2, {link_number_2}, hit_position_2, {hit_normal_2}, ... , status_code] where {} indicates optional data. + + ll.Ceil + + arguments + + + Value + + tooltip + + type + float + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns smallest integer value >= Value. + + ll.Char + + arguments + + + value + + tooltip + Unicode value to convert into a string. + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a single character string that is the representation of the unicode value. + + ll.ClearCameraParams + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Resets all camera parameters to default values and turns off scripted camera control. + + ll.ClearLinkMedia + + arguments + + + Link + + tooltip + + type + integer + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Clears (deletes) the media and all parameters from the given Face on the linked prim.\nReturns an integer that is a STATUS_* flag, which details the success/failure of the operation. + + ll.ClearPrimMedia + + arguments + + + Face + + tooltip + Number of side to clear. + type + integer + + + + energy + 10 + return + integer + sleep + 1 + tooltip + Clears (deletes) the media and all parameters from the given Face.\nReturns an integer that is a STATUS_* flag which details the success/failure of the operation. + + ll.CloseRemoteDataChannel + + arguments + + + ChannelID + + tooltip + + type + key + + + + energy + 10 + return + void + sleep + 1 + tooltip + This function is deprecated. + + ll.Cloud + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the cloud density at the object's position + Offset. + + ll.CollisionFilter + + arguments + + + ObjectName + + tooltip + + type + string + + + + ObjectID + + tooltip + + type + key + + + + Accept + + tooltip + If TRUE, only accept collisions with ObjectName name AND ObjectID (either is optional), otherwise with objects not ObjectName AND ObjectID. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Specify an empty string or NULL_KEY for Accept, to not filter on the corresponding parameter. + + ll.CollisionSound + + arguments + + + ImpactSound + + tooltip + + type + string + + + + ImpactVolume + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Suppress default collision sounds, replace default impact sounds with ImpactSound.\nThe ImpactSound must be in the object inventory.\nSupply an empty string to suppress collision sounds. + + ll.CollisionSprite + + arguments + + + ImpactSprite + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Suppress default collision sprites, replace default impact sprite with ImpactSprite; found in the object inventory (empty string to just suppress). + + ll.ComputeHash + + arguments + + + Message + + tooltip + The message to be hashed. + type + string + + + + Algorithm + + tooltip + The digest algorithm: md5, sha1, sha224, sha256, sha384, sha512. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns hex-encoded Hash string of Message using digest Algorithm. + + ll.Cos + + arguments + + + Theta + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the cosine of Theta (Theta in radians). + + ll.CreateCharacter + + arguments + + + Options + + tooltip + + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Convert link-set to AI/Physics character.\nCreates a path-finding entity, known as a "character", from the object containing the script. Required to activate use of path-finding functions.\nOptions is a list of key/value pairs. + + ll.CreateKeyValue + + arguments + + + Key + + tooltip + + type + string + + + + Value + + tooltip + + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + + Starts an asychronous transaction to create a key-value pair. Will fail with XP_ERROR_STORAGE_EXCEPTION if the key already exists. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value passed to the function. + + + ll.CreateLink + + arguments + + + TargetPrim + + tooltip + Object UUID that is in the same region. + type + key + + + + Parent + + tooltip + If FALSE, then TargetPrim becomes the root. If TRUE, then the script's object becomes the root. + type + integer + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Attempt to link the object the script is in, to target (requires permission PERMISSION_CHANGE_LINKS be set).\nRequires permission PERMISSION_CHANGE_LINKS be set. + + ll.Damage + + arguments + + + target + + tooltip + Agent or task to receive damage. + type + key + + + + damage + + tooltip + Damage amount to inflict on this target. + type + float + + + + type + + tooltip + Damage type to inflict on this target. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Generates a damage event on the targeted agent or task. + + ll.DataSizeKeyValue + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + + Starts an asychronous transaction the request the used and total amount of data allocated for the Experience. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the the amount in use and the third item will be the total available. + + + ll.DeleteCharacter + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Convert link-set from AI/Physics character to Physics object.\nConvert the current link-set back to a standard object, removing all path-finding properties. + + ll.DeleteKeyValue + + arguments + + + Key + + tooltip + + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + + Starts an asychronous transaction to delete a key-value pair. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. + + + ll.DeleteSubList + + arguments + + + Source + + tooltip + + type + list + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Removes the slice from start to end and returns the remainder of the list.\nRemove a slice from the list and return the remainder, start and end are inclusive.\nUsing negative numbers for start and/or end causes the index to count backwards from the length of the list, so 0, -1 would delete the entire list.\nIf Start is larger than End the list deleted is the exclusion of the entries; so 6, 4 would delete the entire list except for the 5th. list entry. + + ll.DeleteSubString + + arguments + + + Source + + tooltip + + type + string + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Removes the indicated sub-string and returns the result.\nStart and End are inclusive.\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would delete the entire string.\nIf Start is larger than End, the sub-string is the exclusion of the entries; so 6, 4 would delete the entire string except for the 5th. character. + + ll.DerezObject + + arguments + + + ID + + tooltip + The ID of an object in the region. + type + key + + + + flags + + tooltip + Flags for derez behavior. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Derezzes an object previously rezzed by a script in this region. Returns TRUE on success or FALSE if the object could not be derezzed. + + ll.DetachFromAvatar + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Remove the object containing the script from the avatar. + + ll.DetectedDamage + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list containing the current damage for the event, the damage type and the original damage delivered. + + ll.DetectedGrab + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the grab offset of a user touching the object.\nReturns <0.0, 0.0, 0.0> if Number is not a valid object. + + ll.DetectedGroup + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns TRUE if detected object or agent Number has the same user group active as this object.\nIt will return FALSE if the object or agent is in the group, but the group is not active. + + ll.DetectedKey + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key of detected object or avatar number.\nReturns NULL_KEY if Number is not a valid index. + + ll.DetectedLinkNumber + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the link position of the triggered event for touches and collisions only.\n0 for a non-linked object, 1 for the root of a linked object, 2 for the first child, etc. + + ll.DetectedName + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the name of detected object or avatar number.\nReturns the name of detected object number.\nReturns empty string if Number is not a valid index. + + ll.DetectedOwner + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key of detected object's owner.\nReturns invalid key if Number is not a valid index. + + ll.DetectedPos + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the position of detected object or avatar number.\nReturns <0.0, 0.0, 0.0> if Number is not a valid index. + + ll.DetectedRezzer + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key for the rezzer of the detected object. + + ll.DetectedRot + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation of detected object or avatar number.\nReturns <0.0, 0.0, 0.0, 1.0> if Number is not a valid offset. + + ll.DetectedTouchBinormal + + arguments + + + Index + + tooltip + Index of detection information + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the surface bi-normal for a triggered touch event.\nReturns a vector that is the surface bi-normal (tangent to the surface) where the touch event was triggered. + + ll.DetectedTouchFace + + arguments + + + Index + + tooltip + Index of detection information + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the index of the face where the avatar clicked in a triggered touch event. + + ll.DetectedTouchNormal + + arguments + + + Index + + tooltip + Index of detection information + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the surface normal for a triggered touch event.\nReturns a vector that is the surface normal (perpendicular to the surface) where the touch event was triggered. + + ll.DetectedTouchPos + + arguments + + + Index + + tooltip + Index of detected information + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the position, in region coordinates, where the object was touched in a triggered touch event.\nUnless it is a HUD, in which case it returns the position relative to the attach point. + + ll.DetectedTouchST + + arguments + + + Index + + tooltip + Index of detection information + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns a vector that is the surface coordinates where the prim was touched.\nThe X and Y vector positions contain the horizontal (S) and vertical (T) face coordinates respectively.\nEach component is in the interval [0.0, 1.0].\nTOUCH_INVALID_TEXCOORD is returned if the surface coordinates cannot be determined (e.g. when the viewer does not support this function). + + ll.DetectedTouchUV + + arguments + + + Index + + tooltip + Index of detection information + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns a vector that is the texture coordinates for where the prim was touched.\nThe X and Y vector positions contain the U and V face coordinates respectively.\nTOUCH_INVALID_TEXCOORD is returned if the touch UV coordinates cannot be determined (e.g. when the viewer does not support this function). + + ll.DetectedType + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the type (AGENT, ACTIVE, PASSIVE, SCRIPTED) of detected object.\nReturns 0 if number is not a valid index.\nNote that number is a bit-field, so comparisons need to be a bitwise checked. e.g.:\ninteger iType = llDetectedType(0);\n{\n // ...do stuff with the agent\n} + + ll.DetectedVel + + arguments + + + Number + + tooltip + + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the velocity of the detected object Number.\nReturns<0.0, 0.0, 0.0> if Number is not a valid offset. + + ll.Dialog + + arguments + + + AvatarID + + tooltip + + type + key + + + + Text + + tooltip + + type + string + + + + Buttons + + tooltip + + type + list + + + + Channel + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 1 + tooltip + + Shows a dialog box on the avatar's screen with the message.\n + Up to 12 strings in the list form buttons.\n + If a button is clicked, the name is chatted on Channel.\nOpens a "notify box" in the given avatars screen displaying the message.\n + Up to twelve buttons can be specified in a list of strings. When the user clicks a button, the name of the button is said on the specified channel.\n + Channels work just like llSay(), so channel 0 can be heard by everyone.\n + The chat originates at the object's position, not the avatar's position, even though it is said as the avatar (uses avatar's UUID and Name etc.).\n + Examples:\n + llDialog(who, "Are you a boy or a girl?", [ "Boy", "Girl" ], -4913);\n + llDialog(who, "This shows only an OK button.", [], -192);\n + llDialog(who, "This chats so you can 'hear' it.", ["Hooray"], 0); + + + ll.Die + + arguments + + energy + 0 + return + void + sleep + 0 + tooltip + Delete the object which holds the script. + + ll.DumpList2String + + arguments + + + Source + + tooltip + + type + list + + + + Separator + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the list as a single string, using Separator between the entries.\nWrite the list out as a single string, using Separator between values. + + ll.EdgeOfWorld + + arguments + + + Position + + tooltip + + type + vector + + + + Direction + + tooltip + + type + vector + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Checks to see whether the border hit by Direction from Position is the edge of the world (has no neighboring region).\nReturns TRUE if the line along Direction from Position hits the edge of the world in the current simulator, returns FALSE if that edge crosses into another simulator. + + ll.EjectFromLand + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + void + sleep + 0 + tooltip + Ejects AvatarID from land that you own.\nEjects AvatarID from land that the object owner (group or resident) owns. + + ll.Email + + arguments + + + Address + + tooltip + + type + string + + + + Subject + + tooltip + + type + string + + + + Text + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 20 + tooltip + Sends email to Address with Subject and Message.\nSends an email to Address with Subject and Message. + + ll.EscapeURL + + arguments + + + URL + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + + Returns an escaped/encoded version of url, replacing spaces with %20 etc.\nReturns the string that is the URL-escaped version of URL (replacing spaces with %20, etc.).\n + This function returns the UTF-8 encoded escape codes for selected characters. + + + ll.Euler2Rot + + arguments + + + Vector + + tooltip + + type + vector + + + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation representation of the Euler angles.\nReturns the rotation represented by the Euler Angle. + + ll.Evade + + arguments + + + TargetID + + tooltip + Agent or object to evade. + type + key + + + + Options + + tooltip + No options yet. + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Evade a specified target.\nCharacters will (roughly) try to hide from their pursuers if there is a good hiding spot along their fleeing path. Hiding means no direct line of sight from the head of the character (centre of the top of its physics bounding box) to the head of its pursuer and no direct path between the two on the navigation-mesh. + + ll.ExecCharacterCmd + + arguments + + + Command + + tooltip + Command to send. + type + integer + + + + Options + + tooltip + Height for CHARACTER_CMD_JUMP. + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Execute a character command.\nSend a command to the path system.\nCurrently only supports stopping the current path-finding operation or causing the character to jump. + + ll.Fabs + + arguments + + + Value + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the positive version of Value.\nReturns the absolute value of Value. + + ll.FindNotecardTextCount + + arguments + + + NotecardName + + tooltip + + type + string + + + + Pattern + + tooltip + Regex pattern to find in the notecard text. + type + string + + + + Options + + tooltip + A list of options to control the search. Included for future expansion, should be [] + type + list + + + + energy + 10 + return + key + sleep + 0 + tooltip + + Searches the text of a cached notecard for lines containing the given pattern and returns the + number of matches found through a dataserver event. + + + ll.FindNotecardTextSync + + arguments + + + NotecardName + + tooltip + + type + string + + + + Pattern + + tooltip + Regex pattern to find in the notecard text. + type + string + + + + StartMatch + + tooltip + The number of matches to skip before returning values. + type + integer + + + + Count + + tooltip + The maximum number of matches to return. If 0 this function will return the first 64 matches found. + type + integer + + + + Options + + tooltip + A list of options to control the search. Included for future expansion, should be [] + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + + Searches the text of a cached notecard for lines containing the given pattern. + Returns a list of line numbers and column where a match is found. If the notecard is not in + the cache it returns a list containing a single entry of NAK. If no matches are found an + empty list is returned. + + + ll.FleeFrom + + arguments + + + Source + + tooltip + Global coordinate from which to flee. + type + vector + + + + Distance + + tooltip + Distance in meters to flee from the source. + type + float + + + + Options + + tooltip + No options available at this time. + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Flee from a point.\nDirects a character (llCreateCharacter) to keep away from a defined position in the region or adjacent regions. + + ll.Floor + + arguments + + + Value + + tooltip + + type + float + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns largest integer value <= Value. + + ll.ForceMouselook + + arguments + + + Enable + + tooltip + Boolean, if TRUE when an avatar sits on the prim, the avatar will be forced into mouse-look mode.\nFALSE is the default setting and will undo a previously set TRUE or do nothing. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + If Enable is TRUE any avatar that sits on this object is forced into mouse-look mode.\nAfter calling this function with Enable set to TRUE, any agent sitting down on the prim will be forced into mouse-look.\nJust like llSitTarget, this changes a permanent property of the prim (not the object) and needs to be reset by calling this function with Enable set to FALSE in order to disable it. + + ll.Frand + + arguments + + + Magnitude + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns a pseudo random number in the range [0, Magnitude] or [Magnitude, 0].\nReturns a pseudo-random number between [0, Magnitude]. + + ll.GenerateKey + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + Generates a key (SHA-1 hash) using UUID generation to create a unique key.\nAs the UUID produced is versioned, it should never return a value of NULL_KEY.\nThe specific UUID version is an implementation detail that has changed in the past and may change again in the future. Do not depend upon the UUID that is returned to be version 5 SHA-1 hash. + + ll.GetAccel + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the acceleration of the object relative to the region's axes.\nGets the acceleration of the object. + + ll.GetAgentInfo + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + integer + sleep + 0 + tooltip + + Returns an integer bit-field containing the agent information about id.\n + Returns AGENT_FLYING, AGENT_ATTACHMENTS, AGENT_SCRIPTED, AGENT_SITTING, AGENT_ON_OBJECT, AGENT_MOUSELOOK, AGENT_AWAY, AGENT_BUSY, AGENT_TYPING, AGENT_CROUCHING, AGENT_ALWAYS_RUN, AGENT_WALKING, AGENT_IN_AIR and/or AGENT_FLOATING_VIA_SCRIPTED_ATTACHMENT.\nReturns information about the given agent ID as a bit-field of agent info constants. + + + ll.GetAgentLanguage + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the language code of the preferred interface language of the avatar.\nReturns a string that is the language code of the preferred interface language of the resident. + + ll.GetAgentList + + arguments + + + Scope + + tooltip + The scope (region, parcel, parcel same owner) to return agents for. + type + integer + + + + Options + + tooltip + List of options to apply. Current unused. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Requests a list of agents currently in the region, limited by the scope parameter.\nReturns a list [key UUID-0, key UUID-1, ..., key UUID-n] or [string error_msg] - returns avatar keys for all agents in the region limited to the area(s) specified by scope + + ll.GetAgentSize + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + vector + sleep + 0 + tooltip + If the avatar is in the same region, returns the size of the bounding box of the requested avatar by id, otherwise returns ZERO_VECTOR.\nIf the agent is in the same region as the object, returns the size of the avatar. + + ll.GetAlpha + + arguments + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the alpha value of Face.\nReturns the 'alpha' of the given face. If face is ALL_SIDES the value returned is the mean average of all faces. + + ll.GetAndResetTime + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the script time in seconds and then resets the script timer to zero.\nGets the time in seconds since starting and resets the time to zero. + + ll.GetAnimation + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the name of the currently playing locomotion animation for the avatar id.\nReturns the currently playing animation for the specified avatar ID. + + ll.GetAnimationList + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of keys of playing animations for an avatar.\nReturns a list of keys of all playing animations for the specified avatar ID. + + ll.GetAnimationOverride + + arguments + + + AnimationState + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string that is the name of the animation that is used for the specified animation state\nTo use this function the script must obtain either the PERMISSION_OVERRIDE_ANIMATIONS or PERMISSION_TRIGGER_ANIMATION permission (automatically granted to attached objects). + + ll.GetAttached + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the object's attachment point, or 0 if not attached. + + ll.GetAttachedList + + arguments + + + ID + + tooltip + Avatar to get attachments + type + key + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of keys of all visible (not HUD) attachments on the avatar identified by the ID argument + + ll.GetAttachedListFiltered + + arguments + + + AgentID + + tooltip + An agent in the region. + type + key + + + + Options + + tooltip + A list of option for inventory transfer. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Retrieves a list of attachments on an avatar. + + ll.GetBoundingBox + + arguments + + + ID + + tooltip + + type + key + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns the bounding box around the object (including any linked prims) relative to its root prim, as a list in the format [ (vector) min_corner, (vector) max_corner ]. + + ll.GetCameraAspect + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the current camera aspect ratio (width / height) of the agent who has granted the scripted object PERMISSION_TRACK_CAMERA permissions. If no permissions have been granted: it returns zero. + + ll.GetCameraFOV + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the current camera field of view of the agent who has granted the scripted object PERMISSION_TRACK_CAMERA permissions. If no permissions have been granted: it returns zero. + + ll.GetCameraPos + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the current camera position for the agent the task has permissions for.\nReturns the position of the camera, of the user that granted the script PERMISSION_TRACK_CAMERA. If no user has granted the permission, it returns ZERO_VECTOR. + + ll.GetCameraRot + + arguments + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the current camera orientation for the agent the task has permissions for. If no user has granted the PERMISSION_TRACK_CAMERA permission, returns ZERO_ROTATION. + + ll.GetCenterOfMass + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the prim's centre of mass (unless called from the root prim, where it returns the object's centre of mass). + + ll.GetClosestNavPoint + + arguments + + + Point + + tooltip + A point in region-local space. + type + vector + + + + Options + + tooltip + No options at this time. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Get the closest navigable point to the point provided.\nThe function accepts a point in region-local space (like all the other path-finding methods) and returns either an empty list or a list containing a single vector which is the closest point on the navigation-mesh to the point provided. + + ll.GetColor + + arguments + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the color on Face.\nReturns the color of Face as a vector of red, green, and blue values between 0 and 1. If face is ALL_SIDES the color returned is the mean average of each channel. + + ll.GetCreator + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + Returns a key for the creator of the prim.\nReturns the key of the object's original creator. Similar to llGetOwner. + + ll.GetDate + + arguments + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the current date in the UTC time zone in the format YYYY-MM-DD.\nReturns the current UTC date as YYYY-MM-DD. + + ll.GetDayLength + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of seconds in a day on this parcel. + + ll.GetDayOffset + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of seconds in a day is offset from midnight in this parcel. + + ll.GetDisplayName + + arguments + + + AvatarID + + tooltip + Avatar UUID that is in the same region, or is otherwise known to the region. + type + key + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the display name of an avatar, if the avatar is connected to the current region, or if the name has been cached. Otherwise, returns an empty string. Use llRequestDisplayName if the avatar may be absent from the region. + + ll.GetEnergy + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns how much energy is in the object as a percentage of maximum. + + ll.GetEnv + + arguments + + + DataRequest + + tooltip + The type of data to request. Any other string will cause an empty string to be returned. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string with the requested data about the region. + + ll.GetEnvironment + + arguments + + + Position + + tooltip + Location within the region. + type + vector + + + + EnvParams + + tooltip + List of environment settings requested for the specified parcel location. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a string with the requested data about the region. + + ll.GetExperienceDetails + + arguments + + + ExperienceID + + tooltip + May be NULL_KEY to retrieve the details for the script's Experience + type + key + + + + energy + 10 + return + list + sleep + 0 + tooltip + + Returns a list with the following Experience properties: [Experience Name, Owner ID, Group ID, Experience ID, State, State Message]. State is an integer corresponding to one of the constants XP_ERROR_... and State Message is the string returned by llGetExperienceErrorMessage for that integer. + + + ll.GetExperienceErrorMessage + + arguments + + + Error + + tooltip + An Experience error code to translate. + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + + Returns a string describing the error code passed or the string corresponding with XP_ERROR_UNKNOWN_ERROR if the value is not a valid Experience error code. + + + ll.GetForce + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the force (if the script is physical).\nReturns the current force if the script is physical. + + ll.GetFreeMemory + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of free bytes of memory the script can use.\nReturns the available free space for the current script. This is inaccurate with LSO. + + ll.GetFreeURLs + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of available URLs for the current script.\nReturns an integer that is the number of available URLs. + + ll.GetGMTclock + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the time in seconds since midnight GMT.\nGets the time in seconds since midnight in GMT/UTC. + + ll.GetGeometricCenter + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the vector that is the geometric center of the object relative to the root prim. + + ll.GetHTTPHeader + + arguments + + + HTTPRequestID + + tooltip + A valid HTTP request key + type + key + + + + Header + + tooltip + Header value name + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the value for header for request_id.\nReturns a string that is the value of the Header for HTTPRequestID. + + ll.GetHealth + + arguments + + + ID + + tooltip + The ID of an agent or object in the region. + type + key + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the current health of an avatar or object in the region. + + ll.GetInventoryAcquireTime + + arguments + + + InventoryItem + + tooltip + Name of item in prim inventory. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the time at which the item was placed into this prim's inventory as a timestamp. + + ll.GetInventoryCreator + + arguments + + + InventoryItem + + tooltip + + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns a key for the creator of the inventory item.\nThis function returns the UUID of the creator of item. If item is not found in inventory, the object says "No item named 'name'". + + ll.GetInventoryDesc + + arguments + + + InventoryItem + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the item description of the item in inventory. If item is not found in inventory, the object says "No item named 'name'" to the debug channel and returns an empty string. + + ll.GetInventoryKey + + arguments + + + InventoryItem + + tooltip + + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key that is the UUID of the inventory named.\nReturns the key of the inventory named. + + ll.GetInventoryName + + arguments + + + InventoryType + + tooltip + Inventory item type + type + integer + + + + Index + + tooltip + Index number of inventory item. + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the name of the inventory item of a given type, specified by index number.\nUse the inventory constants INVENTORY_* to specify the type. + + ll.GetInventoryNumber + + arguments + + + InventoryType + + tooltip + Inventory item type + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the quantity of items of a given type (INVENTORY_* flag) in the prim's inventory.\nUse the inventory constants INVENTORY_* to specify the type. + + ll.GetInventoryPermMask + + arguments + + + InventoryItem + + tooltip + Inventory item name. + type + string + + + + BitMask + + tooltip + MASK_BASE, MASK_OWNER, MASK_GROUP, MASK_EVERYONE or MASK_NEXT + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the requested permission mask for the inventory item.\nReturns the requested permission mask for the inventory item defined by InventoryItem. If item is not in the object's inventory, llGetInventoryPermMask returns FALSE and causes the object to say "No item named '<item>'", where "<item>" is item. + + ll.GetInventoryType + + arguments + + + InventoryItem + + tooltip + + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the type of the named inventory item.\nLike all inventory functions, llGetInventoryType is case-sensitive. + + ll.GetKey + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key of the prim the script is attached to.\nGet the key for the object which has this script. + + ll.GetLandOwnerAt + + arguments + + + Position + + tooltip + + type + vector + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key of the land owner, returns NULL_KEY if public.\nReturns the key of the land owner at Position, or NULL_KEY if public. + + ll.GetLinkKey + + arguments + + + LinkNumber + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key of the linked prim LinkNumber.\nReturns the key of LinkNumber in the link set. + + ll.GetLinkMedia + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + Face + + tooltip + The prim's side number + type + integer + + + + Parameters + + tooltip + A list of PRIM_* property constants to return values of. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Get the media parameters for a particular face on linked prim, given the desired list of parameter names. Returns a list of values in the order requested. Returns an empty list if no media exists on the face. + + ll.GetLinkName + + arguments + + + LinkNumber + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the name of LinkNumber in a link set.\nReturns the name of LinkNumber the link set. + + ll.GetLinkNumber + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the link number of the prim containing the script (0 means not linked, 1 the prim is the root, 2 the prim is the first child, etc.).\nReturns the link number of the prim containing the script. 0 means no link, 1 the root, 2 for first child, etc. + + ll.GetLinkNumberOfSides + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of sides of the specified linked prim.\nReturns an integer that is the number of faces (or sides) of the prim link. + + ll.GetLinkPrimitiveParams + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + + + + Parameters + + tooltip + PRIM_* flags. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns the list of primitive attributes requested in the Parameters list for LinkNumber.\nPRIM_* flags can be broken into three categories, face flags, prim flags, and object flags.\n* Supplying a prim or object flag will return that flags attributes.\n* Face flags require the user to also supply a face index parameter. + + ll.GetLinkSitFlags + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the sit flags set on the specified prim in a linkset. + + ll.GetListEntryType + + arguments + + + ListVariable + + tooltip + + type + list + + + + Index + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the type of the index entry in the list (TYPE_INTEGER, TYPE_FLOAT, TYPE_STRING, TYPE_KEY, TYPE_VECTOR, TYPE_ROTATION, or TYPE_INVALID if index is off list).\nReturns the type of the variable at Index in ListVariable. + + ll.GetListLength + + arguments + + + ListVariable + + tooltip + + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of elements in the list.\nReturns the number of elements in ListVariable. + + ll.GetLocalPos + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the position relative to the root.\nReturns the local position of a child object relative to the root. + + ll.GetLocalRot + + arguments + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation local to the root.\nReturns the local rotation of a child object relative to the root. + + ll.GetMass + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the mass of object that the script is attached to.\nReturns the scripted object's mass. When called from a script in a link-set, the parent will return the sum of the link-set weights, while a child will return just its own mass. When called from a script inside an attachment, this function will return the mass of the avatar it's attached to, not its own. + + ll.GetMassMKS + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Acts as llGetMass(), except that the units of the value returned are Kg. + + ll.GetMaxScaleFactor + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the largest multiplicative uniform scale factor that can be successfully applied (via llScaleByFactor()) to the object without violating prim size or linkability rules. + + ll.GetMemoryLimit + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Get the maximum memory a script can use, in bytes. + + ll.GetMinScaleFactor + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the smallest multiplicative uniform scale factor that can be successfully applied (via llScaleByFactor()) to the object without violating prim size or linkability rules. + + ll.GetMoonDirection + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns a normalized vector of the direction of the moon in the parcel.\nReturns the moon's direction on the simulator in the parcel. + + ll.GetMoonRotation + + arguments + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation applied to the moon in the parcel. + + ll.GetNextEmail + + arguments + + + Address + + tooltip + + type + string + + + + Subject + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Fetch the next queued email with that matches the given address and/or subject, via the email event.\nIf the parameters are blank, they are not used for filtering. + + ll.GetNotecardLine + + arguments + + + NotecardName + + tooltip + + type + string + + + + LineNumber + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 0.1000000000000000055511151 + tooltip + Returns LineNumber from NotecardName via the dataserver event. The line index starts at zero.\nIf the requested line is passed the end of the note-card the dataserver event will return the constant EOF string.\nThe key returned by this function is a unique identifier which will be supplied to the dataserver event in the requested parameter. + + ll.GetNotecardLineSync + + arguments + + + NotecardName + + tooltip + + type + string + + + + LineNumber + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns LineNumber from NotecardName. The line index starts at zero.\nIf the requested line is past the end of the note-card the return value will be set to the constant EOF string.\nIf the note-card is not cached on the simulator the return value is the NAK string. + + ll.GetNumberOfNotecardLines + + arguments + + + NotecardName + + tooltip + + type + string + + + + energy + 10 + return + key + sleep + 0.1000000000000000055511151 + tooltip + Returns the number of lines contained within a notecard via the dataserver event.\nThe key returned by this function is a query ID for identifying the dataserver reply. + + ll.GetNumberOfPrims + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of prims in a link set the script is attached to.\nReturns the number of prims in (and avatars seated on) the object the script is in. + + ll.GetNumberOfSides + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of faces (or sides) of the prim.\nReturns the number of sides of the prim which has the script. + + ll.GetObjectAnimationNames + + arguments + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of names of playing animations for an object.\nReturns a list of names of all playing animations for the current object. + + ll.GetObjectDesc + + arguments + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the description of the prim the script is attached to.\nReturns the description of the scripted object/prim. You can set the description using llSetObjectDesc. + + ll.GetObjectDetails + + arguments + + + ID + + tooltip + Prim or avatar UUID that is in the same region. + type + key + + + + Parameters + + tooltip + List of OBJECT_* flags. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of object details specified in the Parameters list for the object or avatar in the region with key ID.\nParameters are specified by the OBJECT_* constants. + + ll.GetObjectLinkKey + + arguments + + + id + + tooltip + UUID of prim + type + key + + + + link_no + + tooltip + Link number to retrieve + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key of the linked prim link_no in a linkset.\nReturns the key of link_no in the link set specified by id. + + ll.GetObjectMass + + arguments + + + ID + + tooltip + + type + key + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the mass of the avatar or object in the region.\nGets the mass of the object or avatar corresponding to ID. + + ll.GetObjectName + + arguments + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the name of the prim which the script is attached to.\nReturns the name of the prim (not object) which contains the script. + + ll.GetObjectPermMask + + arguments + + + Category + + tooltip + Category is one of MASK_BASE, MASK_OWNER, MASK_GROUP, MASK_EVERYONE, or MASK_NEXT + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the permission mask of the requested category for the object. + + ll.GetObjectPrimCount + + arguments + + + ObjectID + + tooltip + + type + key + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the total number of prims for an object in the region.\nReturns the prim count for any object id in the same region. + + ll.GetOmega + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the rotation velocity in radians per second.\nReturns a vector that is the rotation velocity of the object in radians per second. + + ll.GetOwner + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the object owner's UUID.\nReturns the key for the owner of the object. + + ll.GetOwnerKey + + arguments + + + ObjectID + + tooltip + + type + key + + + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the owner of ObjectID.\nReturns the key for the owner of object ObjectID. + + ll.GetParcelDetails + + arguments + + + Position + + tooltip + Location within the region. + type + vector + + + + ParcelDetails + + tooltip + List of details requested for the specified parcel location. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of parcel details specified in the ParcelDetails list for the parcel at Position.\nParameters is one or more of: PARCEL_DETAILS_NAME, _DESC, _OWNER, _GROUP, _AREA, _ID, _SEE_AVATARS.\nReturns a list that is the parcel details specified in ParcelDetails (in the same order) for the parcel at Position. + + ll.GetParcelFlags + + arguments + + + Position + + tooltip + + type + vector + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns a mask of the parcel flags (PARCEL_FLAG_*) for the parcel that includes the point Position.\nReturns a bit-field specifying the parcel flags (PARCEL_FLAG_*) for the parcel at Position. + + ll.GetParcelMaxPrims + + arguments + + + Position + + tooltip + Region coordinates (z is ignored) of parcel. + type + vector + + + + SimWide + + tooltip + Boolean. If FALSE then the return is the maximum prims supported by the parcel. If TRUE then it is the combined number of prims on all parcels in the region owned by the specified parcel's owner. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the maximum number of prims allowed on the parcel at Position for a given scope.\nThe scope may be set to an individual parcel or the combined resources of all parcels with the same ownership in the region. + + ll.GetParcelMusicURL + + arguments + + energy + 10 + return + string + sleep + 0 + tooltip + Gets the streaming audio URL for the parcel object is on.\nThe object owner, avatar or group, must also be the land owner. + + ll.GetParcelPrimCount + + arguments + + + Position + + tooltip + Region coordinates of parcel to query. + type + vector + + + + Category + + tooltip + A PARCEL_COUNT_* flag. + type + integer + + + + SimWide + + tooltip + Boolean. If FALSE then the return is the maximum prims supported by the parcel. If TRUE then it is the combined number of prims on all parcels in the region owned by the specified parcel's owner. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of prims on the parcel at Position of the given category.\nCategories: PARCEL_COUNT_TOTAL, _OWNER, _GROUP, _OTHER, _SELECTED, _TEMP.\nReturns the number of prims used on the parcel at Position which are in Category.\nIf SimWide is TRUE, it returns the total number of objects for all parcels with matching ownership in the category specified.\nIf SimWide is FALSE, it returns the number of objects on this specific parcel in the category specified + + ll.GetParcelPrimOwners + + arguments + + + Position + + tooltip + + type + vector + + + + energy + 10 + return + list + sleep + 2 + tooltip + Returns a list of up to 100 residents who own objects on the parcel at Position, with per-owner land impact totals.\nRequires owner-like permissions for the parcel, and for the script owner to be present in the region.\nThe list is formatted as [ key agentKey1, integer agentLI1, key agentKey2, integer agentLI2, ... ], sorted by agent key.\nThe integers are the combined land impacts of the objects owned by the corresponding agents. + + ll.GetPermissions + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns an integer bitmask of the permissions that have been granted to the script. Individual permissions can be determined using a bit-wise "and" operation against the PERMISSION_* constants + + ll.GetPermissionsKey + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + Returns the key of the avatar that last granted or declined permissions to the script.\nReturns NULL_KEY if permissions were never granted or declined. + + ll.GetPhysicsMaterial + + arguments + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of the form [float gravity_multiplier, float restitution, float friction, float density]. + + ll.GetPos + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the position of the task in region coordinates.\nReturns the vector position of the task in region coordinates. + + ll.GetPrimMediaParams + + arguments + + + Face + + tooltip + face number + type + integer + + + + Parameters + + tooltip + One or more PRIM_MEDIA_* flags + type + list + + + + energy + 10 + return + list + sleep + 1 + tooltip + Returns the media parameters for a particular face on an object, given the desired list of parameter names, in the order requested. Returns an empty list if no media exists on the face. + + ll.GetPrimitiveParams + + arguments + + + Parameters + + tooltip + PRIM_* flags and face parameters + type + list + + + + energy + 10 + return + list + sleep + 0.2000000000000000111022302 + tooltip + Returns the primitive parameters specified in the parameters list.\nReturns primitive parameters specified in the Parameters list. + + ll.GetRegionAgentCount + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of avatars in the region.\nReturns an integer that is the number of avatars in the region. + + ll.GetRegionCorner + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns a vector, in meters, that is the global location of the south-west corner of the region which the object is in.\nReturns the Region-Corner of the simulator containing the task. The region-corner is a vector (values in meters) representing distance from the first region. + + ll.GetRegionDayLength + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of seconds in a day in this region. + + ll.GetRegionDayOffset + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of seconds in a day is offset from midnight in this parcel. + + ll.GetRegionFPS + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the mean region frames per second. + + ll.GetRegionFlags + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the region flags (REGION_FLAG_*) for the region the object is in.\nReturns a bit-field specifying the region flags (REGION_FLAG_*) for the region the object is in. + + ll.GetRegionMoonDirection + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns a normalized vector of the direction of the moon in the region.\nReturns the moon's direction on the simulator. + + ll.GetRegionMoonRotation + + arguments + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation applied to the moon in the region. + + ll.GetRegionName + + arguments + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the current region name. + + ll.GetRegionSunDirection + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns a normalized vector of the direction of the sun in the region.\nReturns the sun's direction on the simulator. + + ll.GetRegionSunRotation + + arguments + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation applied to the sun in the region. + + ll.GetRegionTimeDilation + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the current time dilation as a float between 0.0 (full dilation) and 1.0 (no dilation).\nReturns the current time dilation as a float between 0.0 and 1.0. + + ll.GetRegionTimeOfDay + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the time in seconds since environmental midnight for the entire region. + + ll.GetRenderMaterial + + arguments + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string that is the render material on face (the inventory name if it is a material in the prim's inventory, otherwise the key).\nReturns the render material of a face, if it is found in object inventory, its key otherwise. + + ll.GetRootPosition + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the position (in region coordinates) of the root prim of the object which the script is attached to.\nThis is used to allow a child prim to determine where the root is. + + ll.GetRootRotation + + arguments + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation (relative to the region) of the root prim of the object which the script is attached to.\nGets the global rotation of the root object of the object script is attached to. + + ll.GetRot + + arguments + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation relative to the region's axes.\nReturns the rotation. + + ll.GetSPMaxMemory + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the maximum used memory for the current script. Only valid after using PROFILE_SCRIPT_MEMORY. Non-mono scripts always use 16k.\nReturns the integer of the most bytes used while llScriptProfiler was last active. + + ll.GetScale + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the scale of the prim.\nReturns a vector that is the scale (dimensions) of the prim. + + ll.GetScriptName + + arguments + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the name of the script that this function is used in.\nReturns the name of this script. + + ll.GetScriptState + + arguments + + + ScriptName + + tooltip + + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns TRUE if the script named is running.\nReturns TRUE if ScriptName is running. + + ll.GetSimStats + + arguments + + + StatType + + tooltip + Statistic type. + type + integer + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns a float that is the requested statistic. + + ll.GetSimulatorHostname + + arguments + + energy + 10 + return + string + sleep + 10 + tooltip + Returns the host-name of the machine which the script is running on.\nFor example, "sim225.agni.lindenlab.com". + + ll.GetStartParameter + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns an integer that is the script rez parameter.\nIf the object was rezzed by an agent, this function returns 0. + + ll.GetStartString + + arguments + + energy + 10 + return + string + sleep + 0 + tooltip + Returns an string that is the value passed to llRezObjectWithParams with REZ_PARAM_STRING.\nIf the object was rezzed by an agent, this function returns an empty string. + + ll.GetStaticPath + + arguments + + + Start + + tooltip + Starting position. + type + vector + + + + End + + tooltip + Ending position. + type + vector + + + + Radius + + tooltip + Radius of the character that the path is for, between 0.125m and 5.0m. + type + float + + + + Parameters + + tooltip + Currently only accepts the parameter CHARACTER_TYPE; the options are identical to those used for llCreateCharacter. The default value is CHARACTER_TYPE_NONE. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + + + ll.GetStatus + + arguments + + + StatusFlag + + tooltip + A STATUS_* flag + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns boolean value of the specified status (e.g. STATUS_PHANTOM) of the object the script is attached to. + + ll.GetSubString + + arguments + + + String + + tooltip + + type + string + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a sub-string from String, in a range specified by the Start and End indicies (inclusive).\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would capture the entire string.\nIf Start is greater than End, the sub string is the exclusion of the entries. + + ll.GetSunDirection + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns a normalized vector of the direction of the sun in the parcel.\nReturns the sun's direction on the simulator in the parcel. + + ll.GetSunRotation + + arguments + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation applied to the sun in the parcel. + + ll.GetTexture + + arguments + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string that is the texture on face (the inventory name if it is a texture in the prim's inventory, otherwise the key).\nReturns the texture of a face, if it is found in object inventory, its key otherwise. + + ll.GetTextureOffset + + arguments + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the texture offset of face in the x and y components of a vector. + + ll.GetTextureRot + + arguments + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the texture rotation of side. + + ll.GetTextureScale + + arguments + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the texture scale of side in the x and y components of a vector.\nReturns the texture scale of a side in the x and y components of a vector. + + ll.GetTime + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the time in seconds since the last region reset, script reset, or call to either llResetTime or llGetAndResetTime. + + ll.GetTimeOfDay + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the time in seconds since environmental midnight on the parcel. + + ll.GetTimestamp + + arguments + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a time-stamp (UTC time zone) in the format: YYYY-MM-DDThh:mm:ss.ff..fZ. + + ll.GetTorque + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the torque (if the script is physical).\nReturns a vector that is the torque (if the script is physical). + + ll.GetUnixTime + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC from the system clock. + + ll.GetUsedMemory + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the current used memory for the current script. Non-mono scripts always use 16K.\nReturns the integer of the number of bytes of memory currently in use by the script. Non-mono scripts always use 16K. + + ll.GetUsername + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the username of an avatar, if the avatar is connected to the current region, or if the name has been cached. Otherwise, returns an empty string. Use llRequestUsername if the avatar may be absent from the region. + + ll.GetVel + + arguments + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the velocity of the object.\nReturns a vector that is the velocity of the object. + + ll.GetVisualParams + + arguments + + + ID + + tooltip + Avatar UUID in the same region. + type + key + + + + Parameters + + tooltip + List of visual parameter IDs. + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of the current value for each requested visual parameter. + + ll.GetWallclock + + arguments + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the time in seconds since midnight California Pacific time (PST/PDT).\nReturns the time in seconds since simulator's time-zone midnight (Pacific Time). + + ll.GiveAgentInventory + + arguments + + + AgentID + + tooltip + An agent in the region. + type + key + + + + FolderName + + tooltip + Folder name to give to the agent. + type + string + + + + InventoryItems + + tooltip + Inventory items to give to the agent. + type + list + + + + Options + + tooltip + A list of option for inventory transfer. + type + list + + + + energy + 10 + return + integer + sleep + 3 + tooltip + Give InventoryItems to the specified agent as a new folder of items, as permitted by the permissions system. The target must be an agent. + + ll.GiveInventory + + arguments + + + TargetID + + tooltip + + type + key + + + + InventoryItem + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Give InventoryItem to destination represented by TargetID, as permitted by the permissions system.\nTargetID may be any agent or an object in the same region. + + ll.GiveInventoryList + + arguments + + + TargetID + + tooltip + + type + key + + + + FolderName + + tooltip + + type + string + + + + InventoryItems + + tooltip + + type + list + + + + energy + 10 + return + void + sleep + 3 + tooltip + Give InventoryItems to destination (represented by TargetID) as a new folder of items, as permitted by the permissions system.\nTargetID may be any agent or an object in the same region. If TargetID is an object, the items are passed directly to the object inventory (no folder is created). + + ll.GiveMoney + + arguments + + + AvatarID + + tooltip + + type + key + + + + Amount + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Transfers Amount of L$ from script owner to AvatarID.\nThis call will silently fail if PERMISSION_DEBIT has not been granted. + + ll.GodLikeRezObject + + arguments + + + InventoryItemID + + tooltip + + type + key + + + + Position + + tooltip + + type + vector + + + + energy + 10 + god-mode + 1 + return + void + sleep + 0 + tooltip + Rez directly off of a UUID if owner has god-bit set. + + ll.Ground + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the ground height at the object position + offset.\nReturns the ground height at the object's position + Offset. + + ll.GroundContour + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the ground contour direction below the object position + Offset.\nReturns the ground contour at the object's position + Offset. + + ll.GroundNormal + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the ground normal below the object position + offset.\nReturns the ground contour at the object's position + Offset. + + ll.GroundRepel + + arguments + + + Height + + tooltip + Distance above the ground. + type + float + + + + Water + + tooltip + Boolean, if TRUE then hover above water too. + type + integer + + + + Tau + + tooltip + Seconds to critically damp in. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + + Critically damps to height if within height * 0.5 of level (either above ground level or above the higher of land and water if water == TRUE).\nCritically damps to fHeight if within fHeight * 0.5 of ground or water level.\n + The height is above ground level if iWater is FALSE or above the higher of land and water if iWater is TRUE.\n + Do not use with vehicles. Only works in physics-enabled objects. + + + ll.GroundSlope + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the ground slope below the object position + Offset.\nReturns the ground slope at the object position + Offset. + + ll.HMAC + + arguments + + + Key + + tooltip + The PEM-formatted key for the hash digest. + type + string + + + + Message + + tooltip + The message to be hashed. + type + string + + + + Algorithm + + tooltip + The digest algorithm: md5, sha1, sha224, sha256, sha384, sha512. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the base64-encoded hashed message authentication code (HMAC), of Message using PEM-formatted Key and digest Algorithm (md5, sha1, sha224, sha256, sha384, sha512). + + ll.HTTPRequest + + arguments + + + URL + + tooltip + A valid HTTP/HTTPS URL. + type + string + + + + Parameters + + tooltip + Configuration parameters, specified as HTTP_* flag-value pairs. + type + list + + + + Body + + tooltip + Contents of the request. + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + Sends an HTTP request to the specified URL with the Body of the request and Parameters.\nReturns a key that is a handle identifying the HTTP request made. + + ll.HTTPResponse + + arguments + + + HTTPRequestID + + tooltip + A valid HTTP request key. + type + key + + + + Status + + tooltip + HTTP Status (200, 400, 404, etc.). + type + integer + + + + Body + + tooltip + Contents of the response. + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Responds to an incoming HTTP request which was triggerd by an http_request event within the script. HTTPRequestID specifies the request to respond to (this ID is supplied in the http_request event handler). Status and Body specify the status code and message to respond with. + + ll.Hash + + arguments + + + value + + tooltip + + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Calculates the 32bit hash value for the provided string. + + ll.InsertString + + arguments + + + TargetVariable + + tooltip + + type + string + + + + Position + + tooltip + + type + integer + + + + SourceVariable + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Inserts SourceVariable into TargetVariable at Position, and returns the result.\nInserts SourceVariable into TargetVariable at Position and returns the result. Note this does not alter TargetVariable. + + ll.InstantMessage + + arguments + + + AvatarID + + tooltip + + type + key + + + + Text + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 2 + tooltip + IMs Text to the user identified.\nSend Text to the user as an instant message. + + ll.IntegerToBase64 + + arguments + + + Value + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string that is a Base64 big endian encode of Value.\nEncodes the Value as an 8-character Base64 string. + + ll.IsFriend + + arguments + + + agent_id + + tooltip + Agent ID of another agent in the region. + type + key + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns TRUE if avatar ID is a friend of the script owner. + + ll.Json2List + + arguments + + + JSON + + tooltip + + type + string + + + + energy + 10 + return + list + sleep + 0 + tooltip + Converts the top level of the JSON string to a list. + + ll.JsonGetValue + + arguments + + + JSON + + tooltip + + type + string + + + + Specifiers + + tooltip + + type + list + + + + energy + 10 + return + string + sleep + 0 + tooltip + Gets the value indicated by Specifiers from the JSON string. + + ll.JsonSetValue + + arguments + + + JSON + + tooltip + + type + string + + + + Specifiers + + tooltip + + type + list + + + + Value + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a new JSON string that is the JSON given with the Value indicated by Specifiers set to Value. + + ll.JsonValueType + + arguments + + + JSON + + tooltip + + type + string + + + + Specifiers + + tooltip + + type + list + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the type constant (JSON_*) for the value in JSON indicated by Specifiers. + + ll.Key2Name + + arguments + + + ID + + tooltip + Avatar or rezzed prim UUID. + type + key + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the name of the prim or avatar specified by ID. The ID must be a valid rezzed prim or avatar key in the current simulator, otherwise an empty string is returned.\nFor avatars, the returned name is the legacy name + + ll.KeyCountKeyValue + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + + Starts an asychronous transaction the request the number of keys in the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will the the number of keys in the system. + + + ll.KeysKeyValue + + arguments + + + First + + tooltip + Index of the first key to return. + type + integer + + + + Count + + tooltip + The number of keys to return. + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + + Starts an asychronous transaction the request a number of keys from the data store. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. The error XP_ERROR_KEY_NOT_FOUND is returned if First is greater than or equal to the number of keys in the data store. In the success case the subsequent items will be the keys requested. The number of keys returned may be less than requested if the return value is too large or if there is not enough keys remaining. The order keys are returned is not guaranteed but is stable between subsequent calls as long as no keys are added or removed. Because the keys are returned in a comma-delimited list it is not recommended to use commas in key names if this function is used. + + + ll.Linear2sRGB + + arguments + + + color + + tooltip + A color in the linear colorspace. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Converts a color from the linear colorspace to sRGB. + + ll.LinkAdjustSoundVolume + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + Volume + + tooltip + The volume to set. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Adjusts the volume (0.0 - 1.0) of the currently playing sound attached to the link.\nThis function has no effect on sounds started with llTriggerSound. + + ll.LinkParticleSystem + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + Rules + + tooltip + Particle system rules list in the format [ rule1, data1, rule2, data2 . . . ruleN, dataN ] + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Creates a particle system in prim LinkNumber based on Rules. An empty list removes a particle system from object.\nList format is [ rule-1, data-1, rule-2, data-2 ... rule-n, data-n ].\nThis is identical to llParticleSystem except that it applies to a specified linked prim and not just the prim the script is in. + + ll.LinkPlaySound + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + Flags + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Plays Sound, once or looping, at Volume (0.0 - 1.0). The sound may be attached to the link or triggered at its location.\nOnly one sound may be attached to an object at a time, and attaching a new sound or calling llStopSound will stop the previously attached sound. + + ll.LinkSetSoundQueueing + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + QueueEnable + + tooltip + Boolean, sound queuing for the linked prim: TRUE enables, FALSE disables (default). + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Limits radius for audibility of scripted sounds (both attached and triggered) to distance Radius around the link. + + ll.LinkSetSoundRadius + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + radius + + tooltip + Maximum distance that sounds can be heard. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Limits radius for audibility of scripted sounds (both attached and triggered) to distance Radius around the link. + + ll.LinkSitTarget + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag of the prim. + type + integer + + + + Offset + + tooltip + Position for the sit target, relative to the prim's position. + type + vector + + + + Rotation + + tooltip + Rotation (relative to the prim's rotation) for the avatar. + type + rotation + + + + energy + 10 + return + void + sleep + 0 + tooltip + Set the sit location for the linked prim(s). If Offset == <0,0,0> clear it.\nSet the sit location for the linked prim(s). The sit location is relative to the prim's position and rotation. + + ll.LinkStopSound + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Stops playback of the currently attached sound on a link. + + ll.LinksetDataAvailable + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of bytes remaining in the linkset's datastore. + + ll.LinksetDataCountFound + + arguments + + + search + + tooltip + A regex search string to match against keys in the datastore. + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of keys matching the regular expression passed in the search parameter. + + ll.LinksetDataCountKeys + + arguments + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the number of keys in the linkset's datastore. + + ll.LinksetDataDelete + + arguments + + + name + + tooltip + Key to delete from the linkset's datastore. + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Deletes a name:value pair from the linkset's datastore. + + ll.LinksetDataDeleteFound + + arguments + + + search + + tooltip + A regex search string to match against keys in the datastore. + type + string + + + + pass + + tooltip + The pass phrase used to protect key value pairs in the linkset data + type + string + + + + energy + 10 + return + list + sleep + 0 + tooltip + Deletes all key value pairs in the linkset data where the key matches the regular expression in search. Returns a list consisting of [ #deleted, #not deleted ]. + + ll.LinksetDataDeleteProtected + + arguments + + + name + + tooltip + Key to delete from the linkset's datastore. + type + string + + + + pass + + tooltip + Pass phrase to access protected data. + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Deletes a name:value pair from the linkset's datastore. + + ll.LinksetDataFindKeys + + arguments + + + search + + tooltip + A regex search string to match against keys in the datastore. + type + string + + + + start + + tooltip + First entry to return. 0 for start of list. + type + integer + + + + count + + tooltip + Number of entries to return. Less than 1 for all keys. + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of keys from the linkset's data store matching the search parameter. + + ll.LinksetDataListKeys + + arguments + + + start + + tooltip + First entry to return. 0 for start of list. + type + integer + + + + count + + tooltip + Number of entries to return. Less than 1 for all keys. + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list of all keys in the linkset datastore. + + ll.LinksetDataRead + + arguments + + + name + + tooltip + Key to retrieve from the linkset's datastore. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the value stored for a key in the linkset. + + ll.LinksetDataReadProtected + + arguments + + + name + + tooltip + Key to retrieve from the linkset's datastore. + type + string + + + + pass + + tooltip + Pass phrase to access protected data. + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the value stored for a key in the linkset. + + ll.LinksetDataReset + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Resets the linkset's data store, erasing all key-value pairs. + + ll.LinksetDataWrite + + arguments + + + name + + tooltip + key for the name:value pair. + type + string + + + + value + + tooltip + value to store in the linkset's datastore. + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Sets a name:value pair in the linkset's datastore + + ll.LinksetDataWriteProtected + + arguments + + + name + + tooltip + key for the name:value pair. + type + string + + + + value + + tooltip + value to store in the linkset's datastore. + type + string + + + + pass + + tooltip + Pass phrase to access protected data. + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Sets a name:value pair in the linkset's datastore + + ll.List2CSV + + arguments + + + ListVariable + + tooltip + + type + list + + + + energy + 10 + return + string + sleep + 0 + tooltip + Creates a string of comma separated values from the list.\nCreate a string of comma separated values from the specified list. + + ll.List2Float + + arguments + + + ListVariable + + tooltip + + type + list + + + + Index + + tooltip + + type + integer + + + + energy + 10 + return + float + sleep + 0 + tooltip + Copies the float at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to a float, then zero is returned. + + ll.List2Integer + + arguments + + + ListVariable + + tooltip + + type + list + + + + Index + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Copies the integer at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to an integer, then zero is returned. + + ll.List2Json + + arguments + + + JsonType + + tooltip + Type is JSON_ARRAY or JSON_OBJECT. + type + string + + + + Values + + tooltip + List of values to convert. + type + list + + + + energy + 10 + return + string + sleep + 0 + tooltip + Converts either a strided list of key:value pairs to a JSON_OBJECT, or a list of values to a JSON_ARRAY. + + ll.List2Key + + arguments + + + ListVariable + + tooltip + + type + list + + + + Index + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + Copies the key at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to a key, then null string is returned. + + ll.List2List + + arguments + + + ListVariable + + tooltip + + type + list + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a subset of entries from ListVariable, in a range specified by the Start and End indicies (inclusive).\nUsing negative numbers for Start and/or End causes the index to count backwards from the length of the string, so 0, -1 would capture the entire string.\nIf Start is greater than End, the sub string is the exclusion of the entries. + + ll.List2ListSlice + + arguments + + + ListVariable + + tooltip + + type + list + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + + Stride + + tooltip + + type + integer + + + + slice_index + + tooltip + + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a subset of entries from ListVariable, in a range specified by Start and End indices (inclusive) return the slice_index element of each stride.\n Using negative numbers for Start and/or End causes the index to count backwards from the length of the list. (e.g. 0, -1 captures entire list)\nIf slice_index is less than 0, it is counted backwards from the end of the stride.\n Stride must be a positive integer > 0 or an empy list is returned. If slice_index falls outside range of stride, an empty list is returned. slice_index is zero-based. (e.g. A stride of 2 has valid indices 0,1) + + ll.List2ListStrided + + arguments + + + ListVariable + + tooltip + + type + list + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + + Stride + + tooltip + + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Copies the strided slice of the list from Start to End.\nReturns a copy of the strided slice of the specified list from Start to End. + + ll.List2Rot + + arguments + + + ListVariable + + tooltip + + type + list + + + + Index + + tooltip + + type + integer + + + + energy + 10 + return + rotation + sleep + 0 + tooltip + Copies the rotation at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to rotation, thenZERO_ROTATION is returned. + + ll.List2String + + arguments + + + ListVariable + + tooltip + + type + list + + + + Index + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Copies the string at Index in the list.\nReturns the value at Index in the specified list as a string. If Index describes a location not in the list then null string is returned. + + ll.List2Vector + + arguments + + + ListVariable + + tooltip + + type + list + + + + Index + + tooltip + + type + integer + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Copies the vector at Index in the list.\nReturns the value at Index in the specified list. If Index describes a location not in the list, or the value cannot be type-cast to a vector, then ZERO_VECTOR is returned. + + ll.ListFindList + + arguments + + + ListVariable + + tooltip + + type + list + + + + Find + + tooltip + + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the index of the first instance of Find in ListVariable. Returns -1 if not found.\nReturns the position of the first instance of the Find list in the ListVariable. Returns -1 if not found. + + ll.ListFindListNext + + arguments + + + ListVariable + + tooltip + + type + list + + + + Find + + tooltip + + type + list + + + + Instance + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the index of the nth instance of Find in ListVariable. Returns -1 if not found. + + ll.ListFindStrided + + arguments + + + ListVariable + + tooltip + + type + list + + + + Find + + tooltip + + type + list + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + + Stride + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the index of the first instance of Find in ListVariable. Returns -1 if not found.\nReturns the position of the first instance of the Find list in the ListVariable after the start index and before the end index. Steps through ListVariable by stride. Returns -1 if not found. + + ll.ListInsertList + + arguments + + + Target + + tooltip + + type + list + + + + ListVariable + + tooltip + + type + list + + + + Position + + tooltip + + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list that contains all the elements from Target but with the elements from ListVariable inserted at Position start.\nReturns a new list, created by inserting ListVariable into the Target list at Position. Note this does not alter the Target. + + ll.ListRandomize + + arguments + + + ListVariable + + tooltip + + type + list + + + + Stride + + tooltip + + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a version of the input ListVariable which has been randomized by blocks of size Stride.\nIf the remainder from the length of the list, divided by the stride is non-zero, this function does not randomize the list. + + ll.ListReplaceList + + arguments + + + Target + + tooltip + + type + list + + + + ListVariable + + tooltip + + type + list + + + + Start + + tooltip + + type + integer + + + + End + + tooltip + + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns a list that is Target with Start through End removed and ListVariable inserted at Start.\nReturns a list replacing the slice of the Target list from Start to End with the specified ListVariable. Start and End are inclusive, so 0, 1 would replace the first two entries and 0, 0 would replace only the first list entry. + + ll.ListSort + + arguments + + + ListVariable + + tooltip + List to sort. + type + list + + + + Stride + + tooltip + Stride length. + type + integer + + + + Ascending + + tooltip + Boolean. TRUE = result in ascending order, FALSE = result in descending order. + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns the specified list, sorted into blocks of stride in ascending order (if Ascending is TRUE, otherwise descending). Note that sort only works if the first entry of each block is the same datatype. + + ll.ListSortStrided + + arguments + + + ListVariable + + tooltip + List to sort. + type + list + + + + Stride + + tooltip + Stride length. + type + integer + + + + Sortkey + + tooltip + The zero based element within the stride to use as the sort key + type + integer + + + + Ascending + + tooltip + Boolean. TRUE = result in ascending order, FALSE = result in descending order. + type + integer + + + + energy + 10 + return + list + sleep + 0 + tooltip + Returns the specified list, sorted by the specified element into blocks of stride in ascending order (if Ascending is TRUE, otherwise descending). Note that sort only works if the first entry of each block is the same datatype. + + ll.ListStatistics + + arguments + + + Operation + + tooltip + One of LIST_STAT_* values + type + integer + + + + ListVariable + + tooltip + Variable to analyze. + type + list + + + + energy + 10 + return + float + sleep + 0 + tooltip + Performs a statistical aggregate function, specified by a LIST_STAT_* constant, on ListVariables.\nThis function allows a script to perform a statistical operation as defined by operation on a list composed of integers and floats. + + ll.Listen + + arguments + + + Channel + + tooltip + + type + integer + + + + SpeakersName + + tooltip + + type + string + + + + SpeakersID + + tooltip + + type + key + + + + Text + + tooltip + + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Creates a listen callback for Text on Channel from SpeakersName and SpeakersID (SpeakersName, SpeakersID, and/or Text can be empty) and returns an identifier that can be used to deactivate or remove the listen.\nNon-empty values for SpeakersName, SpeakersID, and Text will filter the results accordingly, while empty strings and NULL_KEY will not filter the results, for string and key parameters respectively.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. + + ll.ListenControl + + arguments + + + ChannelHandle + + tooltip + + type + integer + + + + Active + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Makes a listen event callback active or inactive. Pass in the value returned from llListen to the iChannelHandle parameter to specify which listener you are controlling.\nUse boolean values to specify Active + + ll.ListenRemove + + arguments + + + ChannelHandle + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Removes a listen event callback. Pass in the value returned from llListen to the iChannelHandle parameter to specify which listener to remove. + + ll.LoadURL + + arguments + + + AvatarID + + tooltip + + type + key + + + + Text + + tooltip + + type + string + + + + URL + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Shows dialog to avatar AvatarID offering to load web page at URL. If user clicks yes, launches their web browser.\nllLoadURL displays a dialogue box to the user, offering to load the specified web page using the default web browser. + + ll.Log + + arguments + + + Value + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the natural logarithm of Value. Returns zero if Value <= 0.\nReturns the base e (natural) logarithm of the specified Value. + + ll.Log10 + + arguments + + + Value + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the base 10 logarithm of Value. Returns zero if Value <= 0.\nReturns the base 10 (common) logarithm of the specified Value. + + ll.LookAt + + arguments + + + Target + + tooltip + + type + vector + + + + Strength + + tooltip + + type + float + + + + Damping + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Cause object name to point its forward axis towards Target, at a force controlled by Strength and Damping.\nGood Strength values are around half the mass of the object and good Damping values are less than 1/10th of the Strength.\nAsymmetrical shapes require smaller Damping. A Strength of 0.0 cancels the look at. + + ll.LoopSound + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Plays specified Sound, looping indefinitely, at Volume (0.0 - 1.0).\nOnly one sound may be attached to an object at a time.\nA second call to llLoopSound with the same key will not restart the sound, but the new volume will be used. This allows control over the volume of already playing sounds.\nSetting the volume to 0 is not the same as calling llStopSound; a sound with 0 volume will continue to loop.\nTo restart the sound from the beginning, call llStopSound before calling llLoopSound again. + + ll.LoopSoundMaster + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Plays attached Sound, looping at volume (0.0 - 1.0), and declares it a sync master.\nBehaviour is identical to llLoopSound, with the addition of marking the source as a "Sync Master", causing "Slave" sounds to sync to it. If there are multiple masters within a viewers interest area, the most audible one (a function of both distance and volume) will win out as the master.\nThe use of multiple masters within a small area is unlikely to produce the desired effect. + + ll.LoopSoundSlave + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Plays attached sound looping at volume (0.0 - 1.0), synced to most audible sync master.\nBehaviour is identical to llLoopSound, unless there is a "Sync Master" present.\nIf a Sync Master is already playing the Slave sound will begin playing from the same point the master is in its loop synchronizing the loop points of both sounds.\nIf a Sync Master is started when the Slave is already playing, the Slave will skip to the correct position to sync with the Master. + + ll.MD5String + + arguments + + + Text + + tooltip + + type + string + + + + Nonce + + tooltip + + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string of 32 hex characters that is an RSA Data Security Inc., MD5 Message-Digest Algorithm of Text with Nonce used as the salt.\nReturns a 32-character hex string. (128-bit in binary.) + + ll.MakeExplosion + + arguments + + + Particles + + tooltip + + type + integer + + + + Scale + + tooltip + + type + float + + + + Velocity + + tooltip + + type + float + + + + Lifetime + + tooltip + + type + float + + + + Arc + + tooltip + + type + float + + + + Texture + + tooltip + + type + string + + + + Offset + + tooltip + + type + vector + + + + deprecated + 1 + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Make a round explosion of particles. Deprecated: Use llParticleSystem instead.\nMake a round explosion of particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead. + + ll.MakeFire + + arguments + + + Particles + + tooltip + + type + integer + + + + Scale + + tooltip + + type + float + + + + Velocity + + tooltip + + type + float + + + + Lifetime + + tooltip + + type + float + + + + Arc + + tooltip + + type + float + + + + Texture + + tooltip + + type + string + + + + Offset + + tooltip + + type + vector + + + + deprecated + 1 + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Make fire like particles. Deprecated: Use llParticleSystem instead.\nMake fire particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead. + + ll.MakeFountain + + arguments + + + Particles + + tooltip + + type + integer + + + + Scale + + tooltip + + type + float + + + + Velocity + + tooltip + + type + float + + + + Lifetime + + tooltip + + type + float + + + + Arc + + tooltip + + type + float + + + + Bounce + + tooltip + + type + integer + + + + Texture + + tooltip + + type + string + + + + Offset + + tooltip + + type + vector + + + + Bounce_Offset + + tooltip + + type + float + + + + deprecated + 1 + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Make a fountain of particles. Deprecated: Use llParticleSystem instead.\nMake a fountain of particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead. + + ll.MakeSmoke + + arguments + + + Particles + + tooltip + + type + integer + + + + Scale + + tooltip + + type + float + + + + Velocity + + tooltip + + type + float + + + + Lifetime + + tooltip + + type + float + + + + Arc + + tooltip + + type + float + + + + Texture + + tooltip + + type + string + + + + Offset + + tooltip + + type + vector + + + + deprecated + 1 + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Make smoke like particles. Deprecated: Use llParticleSystem instead.\nMake smoky particles using texture from the objects inventory. Deprecated: Use llParticleSystem instead. + + ll.ManageEstateAccess + + arguments + + + Action + + tooltip + One of the ESTATE_ACCESS_ALLOWED_* actions. + type + integer + + + + AvatarID + + tooltip + UUID of the avatar or group to act upon. + type + key + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Adds or removes agents from the estate's agent access or ban lists, or groups to the estate's group access list. Action is one of the ESTATE_ACCESS_ALLOWED_* operations to perform.\nReturns an integer representing a boolean, TRUE if the call was successful; FALSE if throttled, invalid action, invalid or null id or object owner is not allowed to manage the estate.\nThe object owner is notified of any changes, unless PERMISSION_SILENT_ESTATE_MANAGEMENT has been granted to the script. + + ll.MapBeacon + + arguments + + + RegionName + + tooltip + Region in which to show the beacon. + type + string + + + + Position + + tooltip + Position within region to show the beacon. + type + vector + + + + Options + + tooltip + Options + type + list + + + + energy + 10 + return + void + sleep + 1 + tooltip + Displays an in world beacon and optionally opens world map for avatar who touched the object or is wearing the script, centered on RegionName with Position highlighted. Only works for scripts attached to avatar, or during touch events. + + ll.MapDestination + + arguments + + + RegionName + + tooltip + + type + string + + + + Position + + tooltip + + type + vector + + + + Direction + + tooltip + + type + vector + + + + energy + 10 + return + void + sleep + 1 + tooltip + Opens world map for avatar who touched is is wearing the script, centred on RegionName with Position highlighted. Only works for scripts attached to avatar, or during touch events.\nDirection currently has no effect. + + ll.MessageLinked + + arguments + + + LinkNumber + + tooltip + + type + integer + + + + Number + + tooltip + + type + integer + + + + Text + + tooltip + + type + string + + + + ID + + tooltip + + type + key + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sends Number, Text, and ID to members of the link set identified by LinkNumber.\nLinkNumber is either a linked number (available through llGetLinkNumber) or a LINK_* constant. + + ll.MinEventDelay + + arguments + + + Delay + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Set the minimum time between events being handled. + + ll.ModPow + + arguments + + + Value + + tooltip + + type + integer + + + + Power + + tooltip + + type + integer + + + + Modulus + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns a Value raised to the Power, mod Modulus. ((a**b)%c) b is capped at 0xFFFF (16 bits).\nReturns (Value ^ Power) % Modulus. (Value raised to the Power, Modulus). Value is capped at 0xFFFF (16 bits). + + ll.ModifyLand + + arguments + + + Action + + tooltip + LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE or LAND_REVERT + type + integer + + + + Area + + tooltip + 0, 1, 2 (2m x 2m, 4m x 4m, or 8m x 8m) + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Modify land with action (LAND_LEVEL, LAND_RAISE, LAND_LOWER, LAND_SMOOTH, LAND_NOISE, LAND_REVERT) on size (0, 1, 2, corresponding to 2m x 2m, 4m x 4m, 8m x 8m). + + ll.MoveToTarget + + arguments + + + Target + + tooltip + + type + vector + + + + Tau + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Critically damp to Target in Tau seconds (if the script is physical).\nCritically damp to position target in tau-seconds if the script is physical. Good tau-values are greater than 0.2. A tau of 0.0 stops the critical damping. + + ll.Name2Key + + arguments + + + Name + + tooltip + Name of agent in region to look up. + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + Look up Agent ID for the named agent in the region. + + ll.NavigateTo + + arguments + + + Location + + tooltip + Region coordinates for the character to navigate to. + type + vector + + + + Options + + tooltip + List of parameters to control the type of path-finding used. Currently only FORCE_DIRECT_PATH supported. + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Navigate to destination.\nDirects an object to travel to a defined position in the region or adjacent regions. + + ll.OffsetTexture + + arguments + + + OffsetS + + tooltip + + type + float + + + + OffsetT + + tooltip + + type + float + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Sets the texture S and T offsets for the chosen Face.\nIf Face is ALL_SIDES this function sets the texture offsets for all faces. + + ll.OpenFloater + + arguments + + + floater_name + + tooltip + Identifier for floater to open + type + string + + + + url + + tooltip + URL to pass to floater + type + string + + + + params + + tooltip + Parameters to apply to open floater + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the value for header for request_id.\nReturns a string that is the value of the Header for HTTPRequestID. + + ll.OpenRemoteDataChannel + + arguments + + deprecated + 1 + energy + 10 + return + void + sleep + 1 + tooltip + This function is deprecated. + + ll.Ord + + arguments + + + value + + tooltip + The string to convert to Unicode. + type + string + + + + index + + tooltip + Index of character to convert to unicode. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns the unicode value of the indicated character in the string. + + ll.OverMyLand + + arguments + + + ID + + tooltip + + type + key + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns TRUE if id ID over land owned by the script owner, otherwise FALSE.\nReturns TRUE if key ID is over land owned by the object owner, FALSE otherwise. + + ll.OwnerSay + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + says Text to owner only (if owner is in region).\nSays Text to the owner of the object running the script, if the owner has been within the object's simulator since logging into Second Life, regardless of where they may be in-world. + + ll.ParcelMediaCommandList + + arguments + + + CommandList + + tooltip + A list of PARCEL_MEDIA_COMMAND_* flags and their parameters + type + list + + + + energy + 10 + return + void + sleep + 2 + tooltip + Controls the playback of multimedia resources on a parcel or for an agent, via one or more PARCEL_MEDIA_COMMAND_* arguments specified in CommandList. + + ll.ParcelMediaQuery + + arguments + + + QueryList + + tooltip + + type + list + + + + energy + 10 + return + list + sleep + 2 + tooltip + Queries the media properties of the parcel containing the script, via one or more PARCEL_MEDIA_COMMAND_* arguments specified in CommandList.\nThis function will only work if the script is contained within an object owned by the land-owner (or if the land is owned by a group, only if the object has been deeded to the group). + + ll.ParseString2List + + arguments + + + Text + + tooltip + + type + string + + + + Separators + + tooltip + + type + list + + + + Spacers + + tooltip + + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Converts Text into a list, discarding Separators, keeping Spacers (Separators and Spacers must be lists of strings, maximum of 8 each).\nSeparators and Spacers are lists of strings with a maximum of 8 entries each. + + ll.ParseStringKeepNulls + + arguments + + + Text + + tooltip + + type + string + + + + Separators + + tooltip + + type + list + + + + Spacers + + tooltip + + type + list + + + + energy + 10 + return + list + sleep + 0 + tooltip + Breaks Text into a list, discarding separators, keeping spacers, keeping any null values generated. (separators and spacers must be lists of strings, maximum of 8 each).\nllParseStringKeepNulls works almost exactly like llParseString2List, except that if a null is found it will add a null-string instead of discarding it like llParseString2List does. + + ll.ParticleSystem + + arguments + + + Parameters + + tooltip + + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Creates a particle system in the prim the script is attached to, based on Parameters. An empty list removes a particle system from object.\nList format is [ rule-1, data-1, rule-2, data-2 ... rule-n, data-n ]. + + ll.PassCollisions + + arguments + + + Pass + + tooltip + Boolean, if TRUE, collisions are passed from children on to parents. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Configures how collision events are passed to scripts in the linkset.\nIf Pass == TRUE, collisions involving collision-handling scripted child prims are also passed on to the root prim. If Pass == FALSE (default behavior), such collisions will only trigger events in the affected child prim. + + ll.PassTouches + + arguments + + + Pass + + tooltip + Boolean, if TRUE, touches are passed from children on to parents. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Configures how touch events are passed to scripts in the linkset.\nIf Pass == TRUE, touches involving touch-handling scripted child prims are also passed on to the root prim. If Pass == FALSE (default behavior), such touches will only trigger events in the affected child prim. + + ll.PatrolPoints + + arguments + + + Points + + tooltip + A list of vectors for the character to travel through sequentially. The list must contain at least two entries. + type + list + + + + Options + + tooltip + No options available at this time. + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Patrol a list of points.\nSets the points for a character (llCreateCharacter) to patrol along. + + ll.PlaySound + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Plays Sound once, at Volume (0.0 - 1.0) and attached to the object.\nOnly one sound may be attached to an object at a time, and attaching a new sound or calling llStopSound will stop the previously attached sound.\nA second call to llPlaySound with the same sound will not restart the sound, but the new volume will be used, which allows control over the volume of already playing sounds.\nTo restart the sound from the beginning, call llStopSound before calling llPlaySound again. + + ll.PlaySoundSlave + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Plays attached Sound once, at Volume (0.0 - 1.0), synced to next loop of most audible sync master.\nBehaviour is identical to llPlaySound, unless there is a "Sync Master" present. If a Sync Master is already playing, the Slave sound will not be played until the Master hits its loop point and returns to the beginning.\nllPlaySoundSlave will play the sound exactly once; if it is desired to have the sound play every time the Master loops, either use llLoopSoundSlave with extra silence padded on the end of the sound or ensure that llPlaySoundSlave is called at least once per loop of the Master. + + ll.Pow + + arguments + + + Value + + tooltip + + type + float + + + + Exponent + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the Value raised to the power Exponent, or returns 0 and triggers Math Error for imaginary results.\nReturns the Value raised to the Exponent. + + ll.PreloadSound + + arguments + + + Sound + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 1 + tooltip + Causes nearby viewers to preload the Sound from the object's inventory.\nThis is intended to prevent delays in starting new sounds when called upon. + + ll.Pursue + + arguments + + + TargetID + + tooltip + Agent or object to pursue. + type + key + + + + Options + + tooltip + Parameters for pursuit. + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Chase after a target.\nCauses the character (llCharacter) to pursue the target defined by TargetID. + + ll.PushObject + + arguments + + + ObjectID + + tooltip + + type + key + + + + Impulse + + tooltip + + type + vector + + + + AngularImpulse + + tooltip + + type + vector + + + + Local + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Applies Impulse and AngularImpulse to ObjectID.\nApplies the supplied impulse and angular impulse to the object specified. + + ll.ReadKeyValue + + arguments + + + Key + + tooltip + + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + + Starts an asychronous transaction to retrieve the value associated with the key given. Will fail with XP_ERROR_KEY_NOT_FOUND if the key does not exist. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. + + + ll.RefreshPrimURL + + arguments + + energy + 10 + return + void + sleep + 20 + tooltip + Reloads the web page shown on the sides of the object. + + ll.RegionSay + + arguments + + + Channel + + tooltip + Any integer value except zero. + type + integer + + + + Text + + tooltip + Message to be transmitted. + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Broadcasts Text to entire region on Channel (except for channel 0). + + ll.RegionSayTo + + arguments + + + TargetID + + tooltip + Avatar or object to say to. + type + key + + + + Channel + + tooltip + Output channel, any integer value. + type + integer + + + + Text + + tooltip + Message to be transmitted. + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Says Text, on Channel, to avatar or object indicated by TargetID (if within region).\nIf TargetID is an avatar and Channel is nonzero, Text can be heard by any attachment on the avatar. + + ll.ReleaseCamera + + arguments + + + AvatarID + + tooltip + + type + key + + + + deprecated + 1 + energy + 10 + return + void + sleep + 0 + tooltip + Return camera to agent.\nDeprecated: Use llClearCameraParams instead. + + ll.ReleaseControls + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Stop taking inputs.\nStop taking inputs from the avatar. + + ll.ReleaseURL + + arguments + + + URL + + tooltip + URL to release. + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Releases the specified URL, which was previously obtained using llRequestURL. Once released, the URL will no longer be usable. + + ll.RemoteDataReply + + arguments + + + ChannelID + + tooltip + + type + key + + + + MessageID + + tooltip + + type + key + + + + sData + + tooltip + String data to send + type + string + + + + iData + + tooltip + Integer data to send + type + integer + + + + deprecated + 1 + energy + 10 + return + void + sleep + 3 + tooltip + This function is deprecated. + + ll.RemoteDataSetRegion + + arguments + + deprecated + 1 + energy + 10 + return + void + sleep + 0 + tooltip + This function is deprecated. + + ll.RemoteLoadScriptPin + + arguments + + + ObjectID + + tooltip + Target prim to attempt copying into. + type + key + + + + ScriptName + + tooltip + Name of the script in current inventory to copy. + type + string + + + + PIN + + tooltip + Integer set on target prim as a Personal Information Number code. + type + integer + + + + Running + + tooltip + If the script should be set running in the target prim. + type + integer + + + + StartParameter + + tooltip + Integer. Parameter passed to the script if set to be running. + type + integer + + + + energy + 10 + return + void + sleep + 3 + tooltip + If the owner of the object containing this script can modify the object identified by the specified object key, and if the PIN matches the PIN previously set using llSetRemoteScriptAccessPin (on the target prim), then the script will be copied into target. Running is a boolean specifying whether the script should be enabled once copied into the target object. + + ll.RemoveFromLandBanList + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Remove avatar from the land ban list.\nRemove specified avatar from the land parcel ban list. + + ll.RemoveFromLandPassList + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Remove avatar from the land pass list.\nRemove specified avatar from the land parcel pass list. + + ll.RemoveInventory + + arguments + + + InventoryItem + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Remove the named inventory item.\nRemove the named inventory item from the object inventory. + + ll.RemoveVehicleFlags + + arguments + + + Vehiclelags + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Removes the enabled bits in 'flags'.\nSets the vehicle flags to FALSE. Valid parameters can be found in the vehicle flags constants section. + + ll.ReplaceAgentEnvironment + + arguments + + + agent_id + + tooltip + + type + key + + + + transition + + tooltip + + type + float + + + + environment + + tooltip + + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Replaces the entire environment for an agent. Must be used as part of an experience. + + ll.ReplaceEnvironment + + arguments + + + position + + tooltip + Location of parcel to change. Use <-1, -1, -1> for entire region. + type + vector + + + + environment + + tooltip + + Name of inventory item, or UUID of environment resource to apply. + Use NULL_KEY or empty string to remove environment. + + type + string + + + + track_no + + tooltip + Elevation zone of where to apply environment. Use -1 for all. + type + integer + + + + day_length + + tooltip + Length of day cycle for this parcel or region. -1 to leave unchanged. + type + integer + + + + day_offset + + tooltip + Offset from GMT for the day cycle on this parcel or region. -1 to leave unchanged. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Replaces the environment for a parcel or region. + + ll.ReplaceSubString + + arguments + + + InitialString + + tooltip + The original string in which to hunt for substring matches. + type + string + + + + SubString + + tooltip + The original substring to find. + type + string + + + + NewSubString + + tooltip + The new substring used to replace. + type + string + + + + Count + + tooltip + The max number of replacements to make. Zero Count means "replace all". Positive Count moves left to right. Negative moves right to left. + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Searches InitialString and replaces instances of SubString with NewSubString. Zero Count means "replace all". Positive Count moves left to right. Negative moves right to left. + + ll.RequestAgentData + + arguments + + + AvatarID + + tooltip + + type + key + + + + Data + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 0.1000000000000000055511151 + tooltip + Requests data about AvatarID. When data is available the dataserver event will be raised.\nThis function requests data about an avatar. If and when the information is collected, the dataserver event is triggered with the key returned from this function passed in the requested parameter. See the agent data constants (DATA_*) for details about valid values of data and what each will return in the dataserver event. + + ll.RequestDisplayName + + arguments + + + AvatarID + + tooltip + Avatar UUID + type + key + + + + energy + 10 + return + key + sleep + 0 + tooltip + Requests the display name of the agent. When the display name is available the dataserver event will be raised.\nThe avatar identified does not need to be in the same region or online at the time of the request.\nReturns a key that is used to identify the dataserver event when it is raised. + + ll.RequestExperiencePermissions + + arguments + + + AgentID + + tooltip + + type + key + + + + unused + + tooltip + Not used, should be "" + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + + Ask the agent for permission to participate in an experience. This request is similar to llRequestPermissions with the following permissions: PERMISSION_TAKE_CONTROLS, PERMISSION_TRIGGER_ANIMATION, PERMISSION_ATTACH, PERMISSION_TRACK_CAMERA, PERMISSION_CONTROL_CAMERA and PERMISSION_TELEPORT. However, unlike llRequestPermissions the decision to allow or block the request is persistent and applies to all scripts using the experience grid wide. Subsequent calls to llRequestExperiencePermissions from scripts in the experience will receive the same response automatically with no user interaction. One of experience_permissions or experience_permissions_denied will be generated in response to this call. Outstanding permission requests will be lost if the script is derezzed, moved to another region or reset. + + + ll.RequestInventoryData + + arguments + + + InventoryItem + + tooltip + + type + string + + + + energy + 10 + return + key + sleep + 1 + tooltip + Requests data for the named InventoryItem.\nWhen data is available, the dataserver event will be raised with the key returned from this function in the requested parameter.\nThe only request currently implemented is to request data from landmarks, where the data returned is in the form "<float, float, float>" which can be cast to a vector. This position is in region local coordinates. + + ll.RequestPermissions + + arguments + + + AvatarID + + tooltip + + type + key + + + + PermissionMask + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Ask AvatarID to allow the script to perform certain actions, specified in the PermissionMask bitmask. PermissionMask should be one or more PERMISSION_* constants. Multiple permissions can be requested simultaneously by ORing the constants together. Many of the permissions requests can only go to object owner.\nThis call will not stop script execution. If the avatar grants the requested permissions, the run_time_permissions event will be called. + + ll.RequestSecureURL + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + Requests one HTTPS:// (SSL) URL for use by this object. The http_request event is triggered with results.\nReturns a key that is the handle used for identifying the request in the http_request event. + + ll.RequestSimulatorData + + arguments + + + RegionName + + tooltip + + type + string + + + + Data + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 1 + tooltip + Requests the specified Data about RegionName. When the specified data is available, the dataserver event is raised.\nData should use one of the DATA_SIM_* constants.\nReturns a dataserver query ID and triggers the dataserver event when data is found. + + ll.RequestURL + + arguments + + energy + 10 + return + key + sleep + 0 + tooltip + Requests one HTTP:// URL for use by this script. The http_request event is triggered with the result of the request.\nReturns a key that is the handle used for identifying the result in the http_request event. + + ll.RequestUserKey + + arguments + + + Name + + tooltip + Name of agent to look up. + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + Look up Agent ID for the named agent using a historical name. + + ll.RequestUsername + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + key + sleep + 0 + tooltip + Requests single-word user-name of an avatar. When data is available the dataserver event will be raised.\nRequests the user-name of the identified agent. When the user-name is available the dataserver event is raised.\nThe agent identified does not need to be in the same region or online at the time of the request.\nReturns a key that is used to identify the dataserver event when it is raised. + + ll.ResetAnimationOverride + + arguments + + + AnimationState + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Resets the animation of the specified animation state to the default value.\nIf animation state equals "ALL", then all animation states are reset. + + ll.ResetLandBanList + + arguments + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Removes all residents from the land ban list. + + ll.ResetLandPassList + + arguments + + energy + 10 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Removes all residents from the land access/pass list. + + ll.ResetOtherScript + + arguments + + + ScriptName + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Resets the named script. + + ll.ResetScript + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Resets the script. + + ll.ResetTime + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the time to zero.\nSets the internal timer to zero. + + ll.ReturnObjectsByID + + arguments + + + ObjectIDs + + tooltip + List of object UUIDs to be returned. + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Return objects using their UUIDs.\nRequires the PERMISSION_RETURN_OBJECTS permission and that the script owner owns the parcel the returned objects are in, or is an estate manager or region owner. + + ll.ReturnObjectsByOwner + + arguments + + + ID + + tooltip + Object owner's UUID. + type + key + + + + Scope + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Return objects based upon their owner and a scope of parcel, parcel owner, or region.\nRequires the PERMISSION_RETURN_OBJECTS permission and that the script owner owns the parcel the returned objects are in, or is an estate manager or region owner. + + ll.RezAtRoot + + arguments + + + InventoryItem + + tooltip + + type + string + + + + Position + + tooltip + + type + vector + + + + Velocity + + tooltip + + type + vector + + + + Rotation + + tooltip + + type + rotation + + + + StartParameter + + tooltip + + type + integer + + + + energy + 200 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Instantiate owner's InventoryItem at Position with Velocity, Rotation and with StartParameter. The last selected root object's location will be set to Position.\nCreates object's inventory item at the given Position, with Velocity, Rotation, and StartParameter. + + ll.RezObject + + arguments + + + InventoryItem + + tooltip + + type + string + + + + Position + + tooltip + + type + vector + + + + Velocity + + tooltip + + type + vector + + + + Rotation + + tooltip + + type + rotation + + + + StartParameter + + tooltip + + type + integer + + + + energy + 200 + return + void + sleep + 0.1000000000000000055511151 + tooltip + Instantiate owners InventoryItem at Position with Velocity, Rotation and with start StartParameter.\nCreates object's inventory item at Position with Velocity and Rotation supplied. The StartParameter value will be available to the newly created object in the on_rez event or through the llGetStartParameter function.\nThe Velocity parameter is ignored if the rezzed object is not physical. + + ll.RezObjectWithParams + + arguments + + + InventoryItem + + tooltip + + type + string + + + + Parms + + tooltip + + type + list + + + + energy + 200 + return + key + sleep + 0.1000000000000000055511151 + tooltip + Instantiate owner's InventoryItem with the given parameters. + + ll.Rot2Angle + + arguments + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the rotation angle represented by Rotation.\nReturns the angle represented by the Rotation. + + ll.Rot2Axis + + arguments + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the rotation axis represented by Rotation.\nReturns the axis represented by the Rotation. + + ll.Rot2Euler + + arguments + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the Euler representation (roll, pitch, yaw) of Rotation.\nReturns the Euler Angle representation of the Rotation. + + ll.Rot2Fwd + + arguments + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the forward vector defined by Rotation.\nReturns the forward axis represented by the Rotation. + + ll.Rot2Left + + arguments + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the left vector defined by Rotation.\nReturns the left axis represented by the Rotation. + + ll.Rot2Up + + arguments + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the up vector defined by Rotation.\nReturns the up axis represented by the Rotation. + + ll.RotBetween + + arguments + + + Vector1 + + tooltip + + type + vector + + + + Vector2 + + tooltip + + type + vector + + + + energy + 10 + return + rotation + sleep + 0 + tooltip + Returns the rotation to rotate Vector1 to Vector2.\nReturns the rotation needed to rotate Vector1 to Vector2. + + ll.RotLookAt + + arguments + + + Rotation + + tooltip + + type + rotation + + + + Strength + + tooltip + + type + float + + + + Damping + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Cause object to rotate to Rotation, with a force function defined by Strength and Damping parameters. Good strength values are around half the mass of the object and good damping values are less than 1/10th of the strength.\nAsymmetrical shapes require smaller damping.\nA strength of 0.0 cancels the look at. + + ll.RotTarget + + arguments + + + Rotation + + tooltip + + type + rotation + + + + LeeWay + + tooltip + + type + float + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Set rotations with error of LeeWay radians as a rotational target, and return an ID for the rotational target.\nThe returned number is a handle that can be used in at_rot_target and llRotTargetRemove. + + ll.RotTargetRemove + + arguments + + + Handle + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Removes rotational target number.\nRemove rotational target indicated by the handle. + + ll.RotateTexture + + arguments + + + Radians + + tooltip + + type + float + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Sets the texture rotation for the specified Face to angle Radians.\nIf Face is ALL_SIDES, rotates the texture of all sides. + + ll.Round + + arguments + + + Value + + tooltip + + type + float + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns Value rounded to the nearest integer.\nReturns the Value rounded to the nearest integer. + + ll.SHA1String + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string of 40 hex characters that is the SHA1 security hash of text. + + ll.SHA256String + + arguments + + + text + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string of 64 hex characters that is the SHA256 security hash of text. + + ll.SameGroup + + arguments + + + ID + + tooltip + + type + key + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns TRUE if avatar ID is in the same region and has the same active group, otherwise FALSE.\nReturns TRUE if the object or agent identified is in the same simulator and has the same active group as this object. Otherwise, returns FALSE. + + ll.Say + + arguments + + + Channel + + tooltip + Channel to use to say text on. + type + integer + + + + Text + + tooltip + Text to say. + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Says Text on Channel.\nThis chat method has a range of 20m radius.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. + + ll.ScaleByFactor + + arguments + + + ScalingFactor + + tooltip + The multiplier to be used with the prim sizes and their local positions. + type + float + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Attempts to resize the entire object by ScalingFactor, maintaining the size-position ratios of the prims.\n\nResizing is subject to prim scale limits and linkability limits. This function can not resize the object if the linkset is physical, a pathfinding character, in a keyframed motion, or if resizing would cause the parcel to overflow.\nReturns a boolean (an integer) TRUE if it succeeds, FALSE if it fails. + + ll.ScaleTexture + + arguments + + + Horizontal + + tooltip + + type + float + + + + Vertical + + tooltip + + type + float + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Sets the diffuse texture Horizontal and Vertical repeats on Face of the prim the script is attached to.\nIf Face == ALL_SIDES, all sides are set in one call.\nNegative values for horizontal and vertical will flip the texture. + + ll.ScriptDanger + + arguments + + + Position + + tooltip + + type + vector + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns TRUE if Position is over public land, sandbox land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts.\nReturns true if the position is over public land, land that doesn't allow everyone to edit and build, or land that doesn't allow outside scripts. + + ll.ScriptProfiler + + arguments + + + State + + tooltip + PROFILE_NONE or PROFILE_SCRIPT_MEMORY flags to control the state. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Enables or disables script profiling options. Currently only supports PROFILE_SCRIPT_MEMORY (Mono only) and PROFILE_NONE.\nMay significantly reduce script performance. + + ll.SendRemoteData + + arguments + + + ChannelID + + tooltip + + type + key + + + + Destination + + tooltip + + type + string + + + + Value + + tooltip + + type + integer + + + + Text + + tooltip + + type + string + + + + deprecated + 1 + energy + 10 + return + key + sleep + 3 + tooltip + This function is deprecated. + + ll.Sensor + + arguments + + + Name + + tooltip + Object or avatar name. + type + string + + + + ID + + tooltip + Object or avatar UUID. + type + key + + + + Type + + tooltip + Bit-field mask of AGENT, AGENT_BY_LEGACY_NAME, AGENT_BY_USERNAME, ACTIVE, PASSIVE, and/or SCRIPTED + type + integer + + + + Range + + tooltip + Distance to scan. 0.0 - 96.0m. + type + float + + + + Arc + + tooltip + Angle, in radians, from the local x-axis of the prim to scan. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Performs a single scan for Name and ID with Type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within Range meters and Arc radians of forward vector.\nSpecifying a blank Name, 0 Type, or NULL_KEY ID will prevent filtering results based on that parameter. A range of 0.0 does not perform a scan.\nResults are returned in the sensor and no_sensor events. + + ll.SensorRemove + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + removes sensor.\nRemoves the sensor set by llSensorRepeat. + + ll.SensorRepeat + + arguments + + + Name + + tooltip + Object or avatar name. + type + string + + + + ID + + tooltip + Object or avatar UUID. + type + key + + + + Type + + tooltip + Bit-field mask of AGENT, AGENT_BY_LEGACY_NAME, AGENT_BY_USERNAME, ACTIVE, PASSIVE, and/or SCRIPTED + type + integer + + + + Range + + tooltip + Distance to scan. 0.0 - 96.0m. + type + float + + + + Arc + + tooltip + Angle, in radians, from the local x-axis of the prim to scan. + type + float + + + + Rate + + tooltip + Period, in seconds, between scans. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Initiates a periodic scan every Rate seconds, for Name and ID with Type (AGENT, ACTIVE, PASSIVE, and/or SCRIPTED) within Range meters and Arc radians of forward vector.\nSpecifying a blank Name, 0 Type, or NULL_KEY ID will prevent filtering results based on that parameter. A range of 0.0 does not perform a scan.\nResults are returned in the sensor and no_sensor events. + + ll.SetAgentEnvironment + + arguments + + + agent_id + + tooltip + Agent to receive new environment settings. + type + key + + + + transition + + tooltip + Number of seconds over which to apply new settings. + type + float + + + + Settings + + tooltip + List of environment settings to replace for agent. + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Sets an agent's environmental values to the specified values. Must be used as part of an experience. + + ll.SetAgentRot + + arguments + + + rot + + tooltip + Rotation to turn the avatar to face. + type + rotation + + + + flags + + tooltip + flags + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the avatar rotation to the given value. + + ll.SetAlpha + + arguments + + + Opacity + + tooltip + + type + float + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the alpha (opacity) of Face.\nSets the alpha (opacity) value for Face. If Face is ALL_SIDES, sets the alpha for all faces. The alpha value is interpreted as an opacity percentage (1.0 is fully opaque, and 0.2 is mostly transparent). This function will clamp alpha values less than 0.1 to 0.1 and greater than 1.0 to 1. + + ll.SetAngularVelocity + + arguments + + + AngVel + + tooltip + The angular velocity to set the object to. + type + vector + + + + Local + + tooltip + If TRUE, the AngVel is treated as a local directional vector instead of a regional directional vector. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets an object's angular velocity to AngVel, in local coordinates if Local == TRUE (if the script is physical).\nHas no effect on non-physical objects. + + ll.SetAnimationOverride + + arguments + + + AnimationState + + tooltip + + type + string + + + + AnimationName + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the animation (in object inventory) that will play for the given animation state.\nTo use this function the script must obtain the PERMISSION_OVERRIDE_ANIMATIONS permission. + + ll.SetBuoyancy + + arguments + + + Buoyancy + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Set the tasks buoyancy (0 is none, < 1.0 sinks, 1.0 floats, > 1.0 rises).\nSet the object buoyancy. A value of 0 is none, less than 1.0 sinks, 1.0 floats, and greater than 1.0 rises. + + ll.SetCameraAtOffset + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the camera used in this object, at offset, if an avatar sits on it.\nSets the offset that an avatar's camera will be moved to if the avatar sits on the object. + + ll.SetCameraEyeOffset + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the camera eye offset used in this object if an avatar sits on it. + + ll.SetCameraParams + + arguments + + + Parameters + + tooltip + + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets multiple camera parameters at once. List format is [ rule-1, data-1, rule-2, data-2 . . . rule-n, data-n ]. + + ll.SetClickAction + + arguments + + + Action + + tooltip + A CLICK_ACTION_* flag + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the action performed when a prim is clicked upon. + + ll.SetColor + + arguments + + + Color + + tooltip + + type + vector + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the color, for the face.\nSets the color of the side specified. If Face is ALL_SIDES, sets the color on all faces. + + ll.SetContentType + + arguments + + + HTTPRequestID + + tooltip + A valid http_request() key + type + key + + + + ContentType + + tooltip + Media type to use with any following llHTTPResponse(HTTPRequestID, ...) + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Set the media type of an LSL HTTP server response to ContentType.\nHTTPRequestID must be a valid http_request ID. ContentType must be one of the CONTENT_TYPE_* constants. + + ll.SetDamage + + arguments + + + Damage + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the amount of damage that will be done to an avatar that this task hits. Task will be killed.\nSets the amount of damage that will be done to an avatar that this object hits. This object will be destroyed on damaging an avatar, and no collision event is triggered. + + ll.SetEnvironment + + arguments + + + Position + + tooltip + Location within the region. + type + vector + + + + EnvParams + + tooltip + List of environment settings to change for the specified parcel location. + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns a string with the requested data about the region. + + ll.SetForce + + arguments + + + Force + + tooltip + Directional force. + type + vector + + + + Local + + tooltip + Boolean, if TRUE uses local axis, if FALSE uses region axis. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets Force on object, in object-local coordinates if Local == TRUE (otherwise, the region reference frame is used).\nOnly works on physical objects. + + ll.SetForceAndTorque + + arguments + + + Force + + tooltip + Directional force. + type + vector + + + + Torque + + tooltip + Torque force. + type + vector + + + + Local + + tooltip + Boolean, if TRUE uses local axis, if FALSE uses region axis. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the Force and Torque of object, in object-local coordinates if Local == TRUE (otherwise, the region reference frame is used).\nOnly works on physical objects. + + ll.SetGroundTexture + + arguments + + + Changes + + tooltip + A list of ground texture properties to change. + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Changes terrain texture properties in the region. + + ll.SetHoverHeight + + arguments + + + Height + + tooltip + Distance above the ground. + type + float + + + + Water + + tooltip + Boolean, if TRUE then hover above water too. + type + integer + + + + Tau + + tooltip + Seconds to critically damp in. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Critically damps a physical object to a Height (either above ground level or above the higher of land and water if water == TRUE).\nDo not use with vehicles. Use llStopHover to stop hovering. + + ll.SetInventoryPermMask + + arguments + + + InventoryItem + + tooltip + An item in the prim's inventory + type + string + + + + PermissionFlag + + tooltip + MASK_* flag + type + integer + + + + PermissionMask + + tooltip + Permission bit-field (PERM_* flags) + type + integer + + + + energy + 10 + god-mode + 1 + return + void + sleep + 0 + tooltip + Sets the given permission mask to the new value on the inventory item. + + ll.SetKeyframedMotion + + arguments + + + Keyframes + + tooltip + Strided keyframe list of the form: position, orientation, time. Each keyframe is interpreted relative to the previous transform of the object. + type + list + + + + Options + + tooltip + + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Requests that a non-physical object be key-framed according to key-frame list.\nSpecify a list of times, positions, and orientations to be followed by an object. The object will be smoothly moved between key-frames by the simulator. Collisions with other non-physical or key-framed objects will be ignored (no script events will fire and collision processing will not occur). Collisions with physical objects will be computed and reported, but the key-framed object will be unaffected by those collisions.\nKeyframes is a strided list containing positional, rotational, and time data for each step in the motion. Options is a list containing optional arguments and parameters (specified by KFM_* constants). + + ll.SetLinkAlpha + + arguments + + + LinkNumber + + tooltip + + type + integer + + + + Opacity + + tooltip + + type + float + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + If a prim exists in the link chain at LinkNumber, set Face to Opacity.\nSets the Face, on the linked prim specified, to the Opacity. + + ll.SetLinkCamera + + arguments + + + LinkNumber + + tooltip + Prim link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + EyeOffset + + tooltip + Offset, relative to the object's centre and expressed in local coordinates, that the camera looks from. + type + vector + + + + LookOffset + + tooltip + Offset, relative to the object's centre and expressed in local coordinates, that the camera looks toward. + type + vector + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the camera eye offset, and the offset that camera is looking at, for avatars that sit on the linked prim. + + ll.SetLinkColor + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + + + + Color + + tooltip + Color in RGB <R.R, G.G, B.B> + type + vector + + + + Face + + tooltip + Side number or ALL_SIDES. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + If a task exists in the link chain at LinkNumber, set the Face to color.\nSets the color of the linked child's side, specified by LinkNumber. + + ll.SetLinkMedia + + arguments + + + Link + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims). + type + integer + + + + Face + + tooltip + Face number. + type + integer + + + + Parameters + + tooltip + A set of name/value pairs (in no particular order) + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Set the media parameters for a particular face on linked prim, specified by Link. Returns an integer that is a STATUS_* flag which details the success/failure of the operation(s).\nMediaParameters is a set of name/value pairs in no particular order. Parameters not specified are unchanged, or if new media is added then set to the default specified. + + ll.SetLinkPrimitiveParams + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + Parameters + + tooltip + + type + list + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Set primitive parameters for LinkNumber based on Parameters.\nSets the parameters (or properties) of any linked prim in one step. + + ll.SetLinkPrimitiveParamsFast + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag + type + integer + + + + Parameters + + tooltip + + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Set primitive parameters for LinkNumber based on Parameters, without a delay.\nSet parameters for link number, from the list of Parameters, with no built-in script sleep. This function is identical to llSetLinkPrimitiveParams, except without the delay. + + ll.SetLinkRenderMaterial + + arguments + + + LinkNumber + + tooltip + + type + integer + + + + RenderMaterial + + tooltip + + type + string + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Sets the Render Material of Face on a linked prim, specified by LinkNumber. Render Materail may be a UUID or name of a material in prim inventory. + + ll.SetLinkSitFlags + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag. + type + integer + + + + Flags + + tooltip + The new set of sit flags to apply to the specified prims in this linkset. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Returns the sit flags set on the specified prim in a linkset. + + ll.SetLinkTexture + + arguments + + + LinkNumber + + tooltip + + type + integer + + + + Texture + + tooltip + + type + string + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Sets the Texture of Face on a linked prim, specified by LinkNumber. Texture may be a UUID or name of a texture in prim inventory. + + ll.SetLinkTextureAnim + + arguments + + + LinkNumber + + tooltip + Link number (0: unlinked, 1: root prim, >1: child prims) or a LINK_* flag to effect + type + integer + + + + Mode + + tooltip + Bitmask of animation options. + type + integer + + + + Face + + tooltip + Specifies which object face to animate or ALL_SIDES. + type + integer + + + + SizeX + + tooltip + Horizontal frames (ignored for ROTATE and SCALE). + type + integer + + + + SizeY + + tooltip + Vertical frames (ignored for ROTATE and SCALE). + type + integer + + + + Start + + tooltip + Start position/frame number (or radians for ROTATE). + type + float + + + + Length + + tooltip + Specifies the animation duration, in frames (or radians for ROTATE). + type + float + + + + Rate + + tooltip + Specifies the animation playback rate, in frames per second (must be greater than zero). + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Animates a texture on the prim specified by LinkNumber, by setting the texture scale and offset.\nMode is a bitmask of animation options.\nFace specifies which object face to animate.\nSizeX and SizeY specify the number of horizontal and vertical frames.Start specifes the animation start point.\nLength specifies the animation duration.\nRate specifies the animation playback rate. + + ll.SetLocalRot + + arguments + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Sets the rotation of a child prim relative to the root prim. + + ll.SetMemoryLimit + + arguments + + + Limit + + tooltip + The amount to reserve, which must be less than the allowed maximum (currently 64KB) and not already have been exceeded. + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Requests Limit bytes to be reserved for this script.\nReturns TRUE or FALSE indicating whether the limit was set successfully.\nThis function has no effect if the script is running in the LSO VM. + + ll.SetObjectDesc + + arguments + + + Description + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the description of the prim to Description.\nThe description field is limited to 127 characters. + + ll.SetObjectName + + arguments + + + Name + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the prim's name to Name. + + ll.SetObjectPermMask + + arguments + + + PermissionFlag + + tooltip + MASK_* flag + type + integer + + + + PermissionMask + + tooltip + Permission bit-field (PERM_* flags) + type + integer + + + + energy + 10 + god-mode + 1 + return + void + sleep + 0 + tooltip + Sets the specified PermissionFlag permission to the value specified by PermissionMask on the object the script is attached to. + + ll.SetParcelMusicURL + + arguments + + + URL + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 2 + tooltip + Sets the streaming audio URL for the parcel the object is on.\nThe object must be owned by the owner of the parcel; if the parcel is group owned the object must be owned by that group. + + ll.SetPayPrice + + arguments + + + Price + + tooltip + The default price shown in the textu input field. + type + integer + + + + QuickButtons + + tooltip + Specifies the 4 payment values shown in the payment dialog's buttons (or PAY_HIDE). + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the default amount when someone chooses to pay this object.\nPrice is the default price shown in the textu input field. QuickButtons specifies the 4 payment values shown in the payment dialog's buttons.\nInput field and buttons may be hidden with PAY_HIDE constant, and may be set to their default values using PAY_DEFAULT. + + ll.SetPhysicsMaterial + + arguments + + + MaterialBits + + tooltip + A bitmask specifying which of the parameters in the other arguments should be applied to the object. + type + integer + + + + GravityMultiplier + + tooltip + + type + float + + + + Restitution + + tooltip + + type + float + + + + Friction + + tooltip + + type + float + + + + Density + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the selected parameters of the object's physics behavior.\nMaterialBits is a bitmask specifying which of the parameters in the other arguments should be applied to the object. GravityMultiplier, Restitution, Friction, and Density are the possible parameters to manipulate. + + ll.SetPos + + arguments + + + Position + + tooltip + Region coordinates to move to (within 10m). + type + vector + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + If the object is not physical, this function sets the position of the prim.\nIf the script is in a child prim, Position is treated as root relative and the link-set is adjusted.\nIf the prim is the root prim, the entire object is moved (up to 10m) to Position in region coordinates. + + ll.SetPrimMediaParams + + arguments + + + Face + + tooltip + Face number + type + integer + + + + MediaParameters + + tooltip + A set of name/value pairs (in no particular order) + type + list + + + + energy + 10 + return + integer + sleep + 1 + tooltip + Sets the MediaParameters for a particular Face on the prim. Returns an integer that is a STATUS_* flag which details the success/failure of the operation(s).\nMediaParameters is a set of name/value pairs in no particular order. Parameters not specified are unchanged, or if new media is added then set to the default specified. + + ll.SetPrimURL + + arguments + + + URL + + tooltip + + type + string + + + + deprecated + 1 + energy + 10 + return + void + sleep + 20 + tooltip + Deprecated: Use llSetPrimMediaParams instead. + + ll.SetPrimitiveParams + + arguments + + + Parameters + + tooltip + A list of changes. + type + list + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + This function changes the many properties (or "parameters") of a prim in one operation. Parameters is a list of changes. + + ll.SetRegionPos + + arguments + + + Position + + tooltip + Vector. The location to move to, in region coordinates. + type + vector + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Attempts to move the object so that the root prim is within 0.1m of Position.\nReturns an integer boolean, TRUE if the object is successfully placed within 0.1 m of Position, FALSE otherwise.\nPosition may be any location within the region or up to 10m across a region border.\nIf the position is below ground, it will be set to the ground level at that x,y location. + + ll.SetRemoteScriptAccessPin + + arguments + + + PIN + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + If PIN is set to a non-zero number, the task will accept remote script loads via llRemoteLoadScriptPin() if it passes in the correct PIN. Othersise, llRemoteLoadScriptPin() is ignored. + + ll.SetRenderMaterial + + arguments + + + Material + + tooltip + + type + string + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Applies Render Material to Face of prim.\nRender Material may be a UUID or name of a material in prim inventory.\nIf Face is ALL_SIDES, set the render material on all faces. + + ll.SetRot + + arguments + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + If the object is not physical, this function sets the rotation of the prim.\nIf the script is in a child prim, Rotation is treated as root relative and the link-set is adjusted.\nIf the prim is the root prim, the entire object is rotated to Rotation in the global reference frame. + + ll.SetScale + + arguments + + + Scale + + tooltip + + type + vector + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the prim's scale (size) to Scale. + + ll.SetScriptState + + arguments + + + ScriptName + + tooltip + + type + string + + + + Running + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Enable or disable the script Running state of Script in the prim. + + ll.SetSitText + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Displays Text rather than 'Sit' in the viewer's context menu. + + ll.SetSoundQueueing + + arguments + + + QueueEnable + + tooltip + Boolean, sound queuing: TRUE enables, FALSE disables (default). + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets whether successive calls to llPlaySound, llLoopSound, etc., (attached sounds) interrupt the currently playing sound.\nThe default for objects is FALSE. Setting this value to TRUE will make the sound wait until the current playing sound reaches its end. The queue is one level deep. + + ll.SetSoundRadius + + arguments + + + Radius + + tooltip + Maximum distance that sounds can be heard. + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Limits radius for audibility of scripted sounds (both attached and triggered) to distance Radius. + + ll.SetStatus + + arguments + + + Status + + tooltip + + type + integer + + + + Value + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets object status specified in Status bitmask (e.g. STATUS_PHYSICS|STATUS_PHANTOM) to boolean Value.\nFor a full list of STATUS_* constants, see wiki documentation. + + ll.SetText + + arguments + + + Text + + tooltip + + type + string + + + + Color + + tooltip + + type + vector + + + + Opacity + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Causes Text to float above the prim, using the specified Color and Opacity. + + ll.SetTexture + + arguments + + + Texture + + tooltip + + type + string + + + + Face + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0.2000000000000000111022302 + tooltip + Applies Texture to Face of prim.\nTexture may be a UUID or name of a texture in prim inventory.\nIf Face is ALL_SIDES, set the texture on all faces. + + ll.SetTextureAnim + + arguments + + + Mode + + tooltip + Mask of Mode flags. + type + integer + + + + Face + + tooltip + Face number or ALL_SIDES. + type + integer + + + + SizeX + + tooltip + Horizontal frames (ignored for ROTATE and SCALE). + type + integer + + + + SizeY + + tooltip + Vertical frames (ignored for ROTATE and SCALE). + type + integer + + + + Start + + tooltip + Start position/frame number (or radians for ROTATE). + type + float + + + + Length + + tooltip + number of frames to display (or radians for ROTATE). + type + float + + + + Rate + + tooltip + Frames per second (must not greater than zero). + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Animates a texture by setting the texture scale and offset.\nMode is a bitmask of animation options.\nFace specifies which object face to animate.\nSizeX and SizeY specify the number of horizontal and vertical frames.Start specifes the animation start point.\nLength specifies the animation duration.\nRate specifies the animation playback rate. + + ll.SetTimerEvent + + arguments + + + Rate + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Causes the timer event to be triggered every Rate seconds.\n Passing in 0.0 stops further timer events. + + ll.SetTorque + + arguments + + + Torque + + tooltip + Torque force. + type + vector + + + + Local + + tooltip + Boolean, if TRUE uses local axis, if FALSE uses region axis. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets the Torque acting on the script's object, in object-local coordinates if Local == TRUE (otherwise, the region reference frame is used).\nOnly works on physical objects. + + ll.SetTouchText + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Displays Text in the viewer context menu that acts on a touch. + + ll.SetVehicleFlags + + arguments + + + Flags + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Enables the vehicle flags specified in the Flags bitmask.\nValid parameters can be found in the wiki documentation. + + ll.SetVehicleFloatParam + + arguments + + + ParameterName + + tooltip + + type + integer + + + + ParameterValue + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets a vehicle float parameter.\nValid parameters can be found in the wiki documentation. + + ll.SetVehicleRotationParam + + arguments + + + ParameterName + + tooltip + + type + integer + + + + ParameterValue + + tooltip + + type + rotation + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets a vehicle rotation parameter.\nValid parameters can be found in the wiki documentation. + + ll.SetVehicleType + + arguments + + + Type + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Activates the vehicle action on the object with vehicle preset Type.\nValid Types and an explanation of their characteristics can be found in wiki documentation. + + ll.SetVehicleVectorParam + + arguments + + + ParameterName + + tooltip + + type + integer + + + + ParameterValue + + tooltip + + type + vector + + + + energy + 10 + return + void + sleep + 0 + tooltip + Sets a vehicle vector parameter.\nValid parameters can be found in the wiki documentation. + + ll.SetVelocity + + arguments + + + Velocity + + tooltip + The velocity to apply. + type + vector + + + + Local + + tooltip + If TRUE, the Velocity is treated as a local directional vector instead of a regional directional vector. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + If the object is physics-enabled, sets the object's linear velocity to Velocity.\nIf Local==TRUE, Velocity is treated as a local directional vector; otherwise, Velocity is treated as a global directional vector. + + ll.Shout + + arguments + + + Channel + + tooltip + + type + integer + + + + Text + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Shouts Text on Channel.\nThis chat method has a range of 100m radius.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. + + ll.SignRSA + + arguments + + + PrivateKey + + tooltip + The PEM-formatted private key + type + string + + + + Message + + tooltip + The message contents to sign + type + string + + + + Algorithm + + tooltip + The digest algorithnm to use: sha1, sha224, sha256, sha384, sha512 + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the base64-encoded RSA signature of Message using PEM-formatted PrivateKey and digest Algorithm (sha1, sha224, sha256, sha384, sha512). + + ll.Sin + + arguments + + + Theta + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the sine of Theta (Theta in radians). + + ll.SitOnLink + + arguments + + + AvatarID + + tooltip + + type + key + + + + LinkID + + tooltip + + type + integer + + + + energy + 10 + return + integer + sleep + 0 + tooltip + If agent identified by AvatarID is participating in the experience, sit them on the specified link's sit target. + + ll.SitTarget + + arguments + + + Offset + + tooltip + + type + vector + + + + Rotation + + tooltip + + type + rotation + + + + energy + 10 + return + void + sleep + 0 + tooltip + Set the sit location for this object. If offset == ZERO_VECTOR, clears the sit target. + + ll.Sleep + + arguments + + + Time + + tooltip + + type + float + + + + energy + 0 + return + void + sleep + 0 + tooltip + Put script to sleep for Time seconds. + + ll.Sound + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + Queue + + tooltip + + type + integer + + + + Loop + + tooltip + + type + integer + + + + deprecated + 1 + energy + 10 + return + void + sleep + 0 + tooltip + Deprecated: Use llPlaySound instead.\nPlays Sound at Volume and specifies whether the sound should loop and/or be enqueued. + + ll.SoundPreload + + arguments + + + Sound + + tooltip + + type + string + + + + deprecated + 1 + energy + 10 + return + void + sleep + 0 + tooltip + Deprecated: Use llPreloadSound instead.\nPreloads a sound on viewers within range. + + ll.Sqrt + + arguments + + + Value + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the square root of Value.\nTriggers a math runtime error for imaginary results (if Value < 0.0). + + ll.StartAnimation + + arguments + + + Animation + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + This function plays the specified animation from playing on the avatar who received the script's most recent permissions request.\nAnimation may be an animation in task inventory or a built-in animation.\nRequires PERMISSION_TRIGGER_ANIMATION. + + ll.StartObjectAnimation + + arguments + + + Animation + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + This function plays the specified animation on the rigged mesh object associated with the current script.\nAnimation may be an animation in task inventory or a built-in animation.\n + + ll.StopAnimation + + arguments + + + Animation + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + This function stops the specified animation on the avatar who received the script's most recent permissions request.\nAnimation may be an animation in task inventory, a built-in animation, or the uuid of an animation.\nRequires PERMISSION_TRIGGER_ANIMATION. + + ll.StopHover + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Stop hovering to a height (due to llSetHoverHeight()). + + ll.StopLookAt + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Stop causing object to point at a target (due to llLookAt() or llRotLookAt()). + + ll.StopMoveToTarget + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Stops critically damped motion (due to llMoveToTarget()). + + ll.StopObjectAnimation + + arguments + + + Animation + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + This function stops the specified animation on the rigged mesh object associated with the current script.\nAnimation may be an animation in task inventory, a built-in animation, or the uuid of an animation.\n + + ll.StopSound + + arguments + + energy + 10 + return + void + sleep + 0 + tooltip + Stops playback of the currently attached sound. + + ll.StringLength + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns an integer that is the number of characters in Text (not counting the null). + + ll.StringToBase64 + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the string Base64 representation of the input string. + + ll.StringTrim + + arguments + + + Text + + tooltip + String to trim + type + string + + + + TrimType + + tooltip + STRING_TRIM_HEAD, STRING_TRIM_TAIL, or STRING_TRIM. + type + integer + + + + energy + 10 + return + string + sleep + 0 + tooltip + Outputs a string, eliminating white-space from the start and/or end of the input string Text.\nValid options for TrimType:\nSTRING_TRIM_HEAD: trim all leading spaces in Text\nSTRING_TRIM_TAIL: trim all trailing spaces in Text\nSTRING_TRIM: trim all leading and trailing spaces in Text. + + ll.SubStringIndex + + arguments + + + Text + + tooltip + + type + string + + + + Sequence + + tooltip + + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns an integer that is the index in Text where string pattern Sequence first appears. Returns -1 if not found. + + ll.TakeCamera + + arguments + + + AvatarID + + tooltip + + type + key + + + + deprecated + 1 + energy + 10 + return + void + sleep + 0 + tooltip + Deprecated: Use llSetCameraParams instead. + + ll.TakeControls + + arguments + + + Controls + + tooltip + Bit-field of CONTROL_* flags. + type + integer + + + + Accept + + tooltip + Boolean, determines whether control events are generated. + type + integer + + + + PassOn + + tooltip + Boolean, determines whether controls are disabled. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Take controls from the agent the script has permissions for.\nIf (Accept == (Controls & input)), send input to the script. PassOn determines whether Controls also perform their normal functions.\nRequires the PERMISSION_TAKE_CONTROLS permission to run. + + ll.Tan + + arguments + + + Theta + + tooltip + + type + float + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the tangent of Theta (Theta in radians). + + ll.Target + + arguments + + + Position + + tooltip + + type + vector + + + + Range + + tooltip + + type + float + + + + energy + 10 + return + integer + sleep + 0 + tooltip + This function is to have the script know when it has reached a position.\nIt registers a Position with a Range that triggers at_target and not_at_target events continuously until unregistered. + + ll.TargetOmega + + arguments + + + Axis + + tooltip + + type + vector + + + + SpinRate + + tooltip + + type + float + + + + Gain + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Attempt to spin at SpinRate with strength Gain on Axis.\nA spin rate of 0.0 cancels the spin. This function always works in object-local coordinates. + + ll.TargetRemove + + arguments + + + Target + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + Removes positional target Handle registered with llTarget. + + ll.TargetedEmail + + arguments + + + Target + + tooltip + + type + integer + + + + Subject + + tooltip + + type + string + + + + Text + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 20 + tooltip + Sends an email with Subject and Message to the owner or creator of an object . + + ll.TeleportAgent + + arguments + + + AvatarID + + tooltip + UUID of avatar. + type + key + + + + LandmarkName + + tooltip + Name of landmark (in object contents), or empty string, to use. + type + string + + + + Position + + tooltip + If no landmark was provided, the position within the current region to teleport the avatar to. + type + vector + + + + LookAtPoint + + tooltip + The position within the target region that the avatar should be turned to face upon arrival. + type + vector + + + + energy + 10 + return + void + sleep + 0 + tooltip + Requests a teleport of avatar to a landmark stored in the object's inventory. If no landmark is provided (an empty string), the avatar is teleported to the location position in the current region. In either case, the avatar is turned to face the position given by look_at in local coordinates.\nRequires the PERMISSION_TELEPORT permission. This function can only teleport the owner of the object. + + ll.TeleportAgentGlobalCoords + + arguments + + + AvatarID + + tooltip + UUID of avatar. + type + key + + + + GlobalPosition + + tooltip + Global coordinates of the destination region. Can be retrieved by using llRequestSimulatorData(region_name, DATA_SIM_POS). + type + vector + + + + RegionPosition + + tooltip + The position within the target region to teleport the avatar to, if no landmark was provided. + type + vector + + + + LookAtPoint + + tooltip + The position within the target region that the avatar should be turned to face upon arrival. + type + vector + + + + energy + 10 + return + void + sleep + 0 + tooltip + Teleports an agent to the RegionPosition local coordinates within a region which is specified by the GlobalPosition global coordinates. The agent lands facing the position defined by LookAtPoint local coordinates.\nRequires the PERMISSION_TELEPORT permission. This function can only teleport the owner of the object. + + ll.TeleportAgentHome + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 100 + return + void + sleep + 5 + tooltip + Teleport agent over the owner's land to agent's home location. + + ll.TextBox + + arguments + + + AvatarID + + tooltip + + type + key + + + + Text + + tooltip + + type + string + + + + Channel + + tooltip + + type + integer + + + + energy + 10 + return + void + sleep + 1 + tooltip + Opens a dialog for the specified avatar with message Text, which contains a text box for input. Any text that is entered is said on the specified Channel (as if by the avatar) when the "OK" button is clicked. + + ll.ToLower + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string that is Text with all lower-case characters. + + ll.ToUpper + + arguments + + + Text + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns a string that is Text with all upper-case characters. + + ll.TransferLindenDollars + + arguments + + + AvatarID + + tooltip + + type + key + + + + Amount + + tooltip + + type + integer + + + + energy + 10 + return + key + sleep + 0 + tooltip + Transfer Amount of linden dollars (L$) from script owner to AvatarID. Returns a key to a corresponding transaction_result event for the success of the transfer.\nAttempts to send the amount of money to the specified avatar, and trigger a transaction_result event identified by the returned key. + + ll.TransferOwnership + + arguments + + + AgentID + + tooltip + An agent in the region. + type + key + + + + Flags + + tooltip + Flags to control type of inventory transfer. + type + integer + + + + Params + + tooltip + Extra parameters to llTransferOwnership. None are defined at this time. + type + list + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Transfers ownership of an object, or a copy of the object to a new agent. + + ll.TriggerSound + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + energy + 10 + return + void + sleep + 0 + tooltip + Plays Sound at Volume (0.0 - 1.0), centered at but not attached to object.\nThere is no limit to the number of triggered sounds which can be generated by an object, and calling llTriggerSound does not affect the attached sounds created by llPlaySound and llLoopSound. This is very useful for things like collision noises, explosions, etc. There is no way to stop or alter the volume of a sound triggered by this function. + + ll.TriggerSoundLimited + + arguments + + + Sound + + tooltip + + type + string + + + + Volume + + tooltip + + type + float + + + + TNE + + tooltip + + type + vector + + + + BSW + + tooltip + + type + vector + + + + energy + 10 + return + void + sleep + 0 + tooltip + Plays Sound at Volume (0.0 - 1.0), centered at but not attached to object, limited to axis-aligned bounding box defined by vectors top-north-east (TNE) and bottom-south-west (BSW).\nThere is no limit to the number of triggered sounds which can be generated by an object, and calling llTriggerSound does not affect the attached sounds created by llPlaySound and llLoopSound. This is very useful for things like collision noises, explosions, etc. There is no way to stop or alter the volume of a sound triggered by this function. + + ll.UnSit + + arguments + + + AvatarID + + tooltip + + type + key + + + + energy + 10 + return + void + sleep + 0 + tooltip + If agent identified by AvatarID is sitting on the object the script is attached to or is over land owned by the objects owner, the agent is forced to stand up. + + ll.UnescapeURL + + arguments + + + URL + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Returns the string that is the URL unescaped, replacing "%20" with spaces, etc., version of URL.\nThis function can output raw UTF-8 strings. + + ll.UpdateCharacter + + arguments + + + Options + + tooltip + Character configuration options. Takes the same constants as llCreateCharacter(). + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Updates settings for a pathfinding character. + + ll.UpdateKeyValue + + arguments + + + Key + + tooltip + + type + string + + + + Value + + tooltip + + type + string + + + + Checked + + tooltip + + type + integer + + + + OriginalValue + + tooltip + + type + string + + + + energy + 10 + return + key + sleep + 0 + tooltip + + Starts an asychronous transaction to update the value associated with the key given. The dataserver callback will be executed with the key returned from this call and a string describing the result. The result is a two element commma-delimited list. The first item is an integer specifying if the transaction succeeded (1) or not (0). In the failure case, the second item will be an integer corresponding to one of the XP_ERROR_... constants. In the success case the second item will be the value associated with the key. If Checked is 1 the existing value in the data store must match the OriginalValue passed or XP_ERROR_RETRY_UPDATE will be returned. If Checked is 0 the key will be created if necessary. + + + ll.VecDist + + arguments + + + Location1 + + tooltip + + type + vector + + + + Location2 + + tooltip + + type + vector + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the distance between Location1 and Location2. + + ll.VecMag + + arguments + + + Vector + + tooltip + + type + vector + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the magnitude of the vector. + + ll.VecNorm + + arguments + + + Vector + + tooltip + + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns normalized vector. + + ll.VerifyRSA + + arguments + + + PublicKey + + tooltip + The PEM-formatted public key for signature verifiation. + type + string + + + + Message + + tooltip + The message that was signed. + type + string + + + + Signature + + tooltip + The base64-formatted signature of the message. + type + string + + + + Algorithm + + tooltip + The digest algorithm: sha1, sha224, sha256, sha384, sha512. + type + string + + + + energy + 10 + return + integer + sleep + 0 + tooltip + Returns TRUE if PublicKey, Message, and Algorithm produce the same base64-formatted Signature. + + ll.VolumeDetect + + arguments + + + DetectEnabled + + tooltip + TRUE enables, FALSE disables. + type + integer + + + + energy + 10 + return + void + sleep + 0 + tooltip + If DetectEnabled = TRUE, object becomes phantom but triggers collision_start and collision_end events when other objects start and stop interpenetrating.\nIf another object (including avatars) interpenetrates it, it will get a collision_start event.\nWhen an object stops interpenetrating, a collision_end event is generated. While the other is inter-penetrating, collision events are NOT generated. + + ll.WanderWithin + + arguments + + + Origin + + tooltip + Central point to wander about. + type + vector + + + + Area + + tooltip + Half-extents of an area the character may wander within. (i.e., it can wander from the specified origin by up to +/-Distance.x in x, +/-Distance.y in y, etc.) + type + vector + + + + Options + + tooltip + No options available at this time. + type + list + + + + energy + 10 + return + void + sleep + 0 + tooltip + Wander within a specified volume.\nSets a character to wander about a central spot within a specified area. + + ll.Water + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + float + sleep + 0 + tooltip + Returns the water height below the object position + Offset. + + ll.Whisper + + arguments + + + Channel + + tooltip + + type + integer + + + + Text + + tooltip + + type + string + + + + energy + 10 + return + void + sleep + 0 + tooltip + Whispers Text on Channel.\nThis chat method has a range of 10m radius.\nPUBLIC_CHANNEL is the public chat channel that all avatars see as chat text. DEBUG_CHANNEL is the script debug channel, and is also visible to nearby avatars. All other channels are are not sent to avatars, but may be used to communicate with scripts. + + ll.Wind + + arguments + + + Offset + + tooltip + + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the wind velocity at the object position + Offset. + + ll.WorldPosToHUD + + arguments + + + world_pos + + tooltip + The world-frame position to project into HUD space + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Returns the local position that would put the origin of a HUD object directly over world_pos as viewed by the current camera. + + ll.XorBase64 + + arguments + + + Text1 + + tooltip + + type + string + + + + Text2 + + tooltip + + type + string + + + + energy + 10 + return + string + sleep + 0 + tooltip + Performs an exclusive OR on two Base64 strings and returns a Base64 string. Text2 repeats if it is shorter than Text1. + + ll.XorBase64Strings + + arguments + + + Text1 + + tooltip + + type + string + + + + Text2 + + tooltip + + type + string + + + + deprecated + 1 + energy + 10 + return + string + sleep + 0.2999999999999999888977698 + tooltip + Deprecated: Please use llXorBase64 instead.\nIncorrectly performs an exclusive OR on two Base64 strings and returns a Base64 string. Text2 repeats if it is shorter than Text1.\nRetained for backwards compatibility. + + ll.XorBase64StringsCorrect + + arguments + + + Text1 + + tooltip + + type + string + + + + Text2 + + tooltip + + type + string + + + + deprecated + 1 + energy + 10 + return + string + sleep + 0 + tooltip + Deprecated: Please use llXorBase64 instead.\nCorrectly (unless nulls are present) performs an exclusive OR on two Base64 strings and returns a Base64 string.\nText2 repeats if it is shorter than Text1. + + ll.sRGB2Linear + + arguments + + + srgb + + tooltip + A color in the sRGB colorspace. + type + vector + + + + energy + 10 + return + vector + sleep + 0 + tooltip + Converts a color from the sRGB to the linear colorspace. + + + ll.sd-lsl-syntax-version + 2 + + + diff --git a/etc/message.xml b/indra/newview/app_settings/message.xml similarity index 100% rename from etc/message.xml rename to indra/newview/app_settings/message.xml diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f4158188ada..0306d243ee5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1159,7 +1159,7 @@ Type Boolean Value - 0 + 1 ShowDiscordActivityDetails @@ -4380,7 +4380,7 @@ Type F32 Value - 40.0 + 90.0 LogMessages @@ -7863,7 +7863,7 @@ RenderMaxOpenGLVersion Comment - Maximum OpenGL version to attempt use (minimum 3.1 maximum 4.6). Requires restart. + Maximum OpenGL version to attempt use (minimum 3.1 maximum 4.6). Requires restart. Windows only. Persist 1 Type @@ -9111,7 +9111,7 @@ RenderQualityPerformance Comment - Which graphics settings you've chosen + Which graphics settings you've chosen. Don't use this setting to change quality directly from debug settings. Persist 1 Type @@ -9119,7 +9119,18 @@ Value 1 - + DebugQualityPerformance + + Comment + Allows to change performance quality directly from debug settings. + Persist + 1 + Type + U32 + Value + 1 + + RenderReflectionDetail Comment @@ -10330,13 +10341,13 @@ SceneLoadRearMaxRadiusFraction Comment - a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold + a fraction of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold Persist 1 Type F32 Value - 75.0 + 0.75 SceneLoadRearPixelThreshold @@ -13036,9 +13047,9 @@ Use24HourClock Comment - 12 vs 24. At the moment only for region restart schedule floater + 12 vs 24. At the moment coverage is partial Persist - 0 + 1 Type Boolean Value @@ -13915,6 +13926,50 @@ Value + ExternalWebsocketSyncEnable + + Comment + Enables the Websocket JSONRPC server when doing external script editing. + Persist + 1 + Type + Boolean + Value + 1 + + ExternalWebsocketSyncPort + + Comment + Port that the JSONRPC server listens on when editing + Persist + 1 + Type + S32 + Value + 9020 + + ExternalWebsocketSyncLocal + + Comment + Should the JSONRPC server listen only for local connections. + Persist + 1 + Type + Boolean + Value + 1 + + ExternalWebsocketForwardDebug + + Comment + Forward messages and runtime errors for a script to JSONRPC client. + Persist + 1 + Type + Boolean + Value + 1 + YawFromMousePosition Comment @@ -16410,5 +16465,16 @@ Value 2 + ScriptEditorDisableSyntaxHighlight + + Comment + Disable syntax highlighting in script editor for performance testing + Persist + 1 + Type + Boolean + Value + 0 + diff --git a/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl b/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl index 017855325c6..8e12d094431 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl @@ -2545,12 +2545,31 @@ A_STATIC void CasSetup( #endif #ifdef A_GPU + +#ifdef LEGACY_GAMMA +uniform float gamma; + +vec3 legacyGamma(vec3 color) +{ + vec3 c = 1. - clamp(color, vec3(0.), vec3(1.)); + c = 1. - pow(c, vec3(gamma)); // s/b inverted already CPU-side + + return c; +} +#endif + void main() { vec4 diff = vec4(0.f); uvec2 point = uvec2(vary_fragcoord * out_screen_res.xy); CasFilter(diff.r, diff.g, diff.b, point, cas_param_0, cas_param_1, true); diff.a = texture(diffuseRect, vary_fragcoord).a; + diff.rgb = linear_to_srgb(diff.rgb); + +#ifdef LEGACY_GAMMA + diff.rgb = legacyGamma(diff.rgb); +#endif + frag_color = diff; } #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl b/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl index fdb77cce6ee..58373089653 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/SMAA.glsl @@ -1351,6 +1351,10 @@ float4 SMAABlendingWeightCalculationPS(float2 texcoord, //----------------------------------------------------------------------------- // Neighborhood Blending Pixel Shader (Third Pass) +vec3 srgb_to_linear(vec3 cs); +vec4 srgb_to_linear4(vec4 cs); +vec3 linear_to_srgb(vec3 cl); + float4 SMAANeighborhoodBlendingPS(float2 texcoord, float4 offset, SMAATexture2D(colorTex), @@ -1369,6 +1373,7 @@ float4 SMAANeighborhoodBlendingPS(float2 texcoord, SMAA_BRANCH if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5) { float4 color = SMAASampleLevelZero(colorTex, texcoord); + color.rgb = srgb_to_linear(color.rgb); #if SMAA_REPROJECTION float2 velocity = SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, texcoord)); @@ -1377,6 +1382,7 @@ float4 SMAANeighborhoodBlendingPS(float2 texcoord, color.a = sqrt(5.0 * length(velocity)); #endif + color.rgb = linear_to_srgb(color.rgb); return color; } else { bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical) @@ -1393,8 +1399,13 @@ float4 SMAANeighborhoodBlendingPS(float2 texcoord, // We exploit bilinear filtering to mix current pixel with the chosen // neighbor: - float4 color = blendingWeight.x * SMAASampleLevelZero(colorTex, blendingCoord.xy); - color += blendingWeight.y * SMAASampleLevelZero(colorTex, blendingCoord.zw); + float4 color = SMAASampleLevelZero(colorTex, blendingCoord.xy); + color.rgb = srgb_to_linear(color.rgb); + color = blendingWeight.x * color; + + float4 color2 = SMAASampleLevelZero(colorTex, blendingCoord.zw); + color2.rgb = srgb_to_linear(color2.rgb); + color += blendingWeight.y * color2; #if SMAA_REPROJECTION // Antialias velocity for proper reprojection in a later stage: @@ -1405,6 +1416,7 @@ float4 SMAANeighborhoodBlendingPS(float2 texcoord, color.a = sqrt(5.0 * length(velocity)); #endif + color.rgb = linear_to_srgb(color.rgb); return color; } } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 4ccc6f54a8c..d7a47ef8cd2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -43,8 +43,6 @@ vec3 legacyGamma(vec3 color) return c; } -vec3 clampHDRRange(vec3 color); - void main() { //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB) @@ -55,7 +53,7 @@ void main() diff.rgb = legacyGamma(diff.rgb); #endif - diff.rgb = clampHDRRange(diff.rgb); + diff.rgb = clamp(diff.rgb, vec3(0.0), vec3(1.0)); frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl index 1f01c7f16a2..b1218d61aff 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl @@ -31,11 +31,25 @@ uniform sampler2D diffuseRect; in vec2 vary_fragcoord; +#ifdef GAMMA_CORRECT +uniform float gamma; +#endif + vec3 linear_to_srgb(vec3 cl); vec3 toneMap(vec3 color); vec3 clampHDRRange(vec3 color); +#ifdef GAMMA_CORRECT +vec3 legacyGamma(vec3 color) +{ + vec3 c = 1. - clamp(color, vec3(0.), vec3(1.)); + c = 1. - pow(c, vec3(gamma)); // s/b inverted already CPU-side + + return c; +} +#endif + void main() { //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB) @@ -47,8 +61,18 @@ void main() diff.rgb = clamp(diff.rgb, vec3(0.0), vec3(1.0)); #endif - diff.rgb = clampHDRRange(diff.rgb); +#ifdef GAMMA_CORRECT + diff.rgb = linear_to_srgb(diff.rgb); + +#ifdef LEGACY_GAMMA + diff.rgb = legacyGamma(diff.rgb); +#endif + +#endif + + diff.rgb = clamp(diff.rgb, vec3(0.0), vec3(1.0)); // We should always be 0-1 past this point + //debugExposure(diff.rgb); - frag_color = max(diff, vec4(0)); + frag_color = diff; } diff --git a/indra/newview/app_settings/types_lua_default.xml b/indra/newview/app_settings/types_lua_default.xml new file mode 100644 index 00000000000..5881df5ba5e --- /dev/null +++ b/indra/newview/app_settings/types_lua_default.xml @@ -0,0 +1,2488 @@ + + + + $schema + ./sl-lua-defs.schema.json + aliases + + list + + aliasTypes + + string + number + integer + vector + uuid + quaternion + boolean + + aliasIndex + number + tooltip + A table with numeric indices containing various value types + + table + + aliasTypes + + any + + aliasIndex + any + tooltip + A table with any type of indices and values + + numeric + + aliasTypes + + number + boolean + integer + + tooltip + A union type representing numeric values + + lljson_constant + + aliasTypes + + number + + tooltip + A constant value used in lljson module + + uuid_like + + aliasTypes + + string + uuid + + tooltip + A union type representing uuid values + + EventHandler + + aliasTypes + + (...any) -> () + + tooltip + A function type for event handlers that accepts variable arguments + + + functions + + toquaternion + + parameters + + + name + str + type + string + + + returnType + quaternion | nil + tooltip + Creates a quaternion from a string argument in format `<1,1,1,1>`. Invalid strings will return `nil`. Due to an old error from LSL, strings that match up to the closing `>` are interpreted as valid. So `<1,1,1,1` and `<1,1,1,1spoon` are both cast to `<1,1,1,1>`. When testing if a string is a quaternion or a vector, you should test with `toquaternion` first. + + tovector + + parameters + + + name + str + type + string + + + returnType + vector | nil + tooltip + Creates a vector from a string argument in format `<1,1,1>`. Invalid strings will return `nil`. Due to an old error from LSL, strings that match up to the closing `>` are interpreted as valid. So `<1,1,1`, `<1,1,1,1` and `<1,1,1spoon` are all cast to `<1,1,1>`. When testing if a string is a quaternion or a vector, you should test with `toquaternion` first. + + integer + + parameters + + + name + value + type + string | number + + + returnType + integer + tooltip + Creates an integer value from argument + + uuid + + parameters + + + name + str + type + string + + + returnType + uuid + tooltip + Creates a uuid from a string argument + + vector + + parameters + + + name + x + type + number + + + name + y + type + number + + + name + z + type + number + + + returnType + vector + tooltip + Creates a vector. + + quaternion + + parameters + + + name + x + type + number + + + name + y + type + number + + + name + z + type + number + + + name + s + type + number + + + returnType + quaternion + tooltip + Creates a quaternion rotation. + + + classes + + integer + + methods + + __add + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + integer + tooltip + Addition operator for integers + + + parameters + + + name + self + type + integer + + + name + other + type + number + + + returnType + number + tooltip + Addition operator for integer and number + + + __sub + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + integer + tooltip + Subtraction operator for integers + + + parameters + + + name + self + type + integer + + + name + other + type + number + + + returnType + number + tooltip + Subtraction operator for integer and number + + + __mul + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + integer + tooltip + Multiplication operator for integers + + + parameters + + + name + self + type + integer + + + name + other + type + number + + + returnType + number + tooltip + Multiplication operator for integer and number + + + __div + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + integer + tooltip + Division operator for integers + + + parameters + + + name + self + type + integer + + + name + other + type + number + + + returnType + number + tooltip + Division operator for integer and number + + + __unm + + + parameters + + + name + self + type + integer + + + returnType + integer + tooltip + Unary minus operator + + + __mod + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + integer + tooltip + Modulo operator for integers + + + parameters + + + name + self + type + integer + + + name + other + type + number + + + returnType + number + tooltip + Modulo operator for integer and number + + + __pow + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + integer + tooltip + Power operator for integers + + + parameters + + + name + self + type + integer + + + name + other + type + number + + + returnType + number + tooltip + Power operator for integer and number + + + __idiv + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + integer + tooltip + Integer division operator for integers + + + parameters + + + name + self + type + integer + + + name + other + type + number + + + returnType + integer + tooltip + Integer division operator for integer and number + + + __eq + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + boolean + tooltip + Equality comparison operator + + + __lt + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + boolean + tooltip + Less than comparison operator + + + __le + + + parameters + + + name + self + type + integer + + + name + other + type + integer + + + returnType + boolean + tooltip + Less than or equal comparison operator + + + + tooltip + Integer class with arithmetic and comparison operators + + uuid + + methods + + __tostring + + + parameters + + + name + self + type + uuid + + + returnType + string + tooltip + Convert UUID to string representation + + + + properties + + istruthy + boolean + + tooltip + UUID class with string conversion and truthiness property + + quaternion + + properties + + x + number + y + number + z + number + s + number + + methods + + __mul + + + parameters + + + name + self + type + quaternion + + + name + other + type + vector + + + returnType + vector + tooltip + Multiply vector by quaternion + + + parameters + + + name + self + type + quaternion + + + name + other + type + quaternion + + + returnType + quaternion + tooltip + Multiply quaternion by quaternion + + + + tooltip + Quaternion class representing a rotation with x, y, z, s components + + vector + + properties + + x + number + y + number + z + number + + methods + + __mul + + + parameters + + + name + self + type + vector + + + name + other + type + vector + + + returnType + vector + tooltip + Multiply vector by vector + + + parameters + + + name + self + type + vector + + + name + other + type + quaternion + + + returnType + vector + tooltip + Multiply vector by quaternion + + + parameters + + + name + self + type + vector + + + name + other + type + number + + + returnType + vector + tooltip + Multiply vector by number + + + __div + + + parameters + + + name + self + type + vector + + + name + other + type + vector + + + returnType + vector + tooltip + Divide vector by vector + + + parameters + + + name + self + type + vector + + + name + other + type + quaternion + + + returnType + vector + tooltip + Divide vector by quaternion + + + parameters + + + name + self + type + vector + + + name + other + type + number + + + returnType + vector + tooltip + Divide vector by number + + + __idiv + + + parameters + + + name + self + type + vector + + + name + other + type + vector + + + returnType + vector + tooltip + Floor divide vector by vector + + + parameters + + + name + self + type + vector + + + name + other + type + quaternion + + + returnType + vector + tooltip + Floor divide vector by quaternion + + + parameters + + + name + self + type + vector + + + name + other + type + number + + + returnType + vector + tooltip + Floor divide vector by number + + + __add + + + parameters + + + name + self + type + vector + + + name + other + type + vector + + + returnType + vector + tooltip + Add two vectors + + + __sub + + + parameters + + + name + self + type + vector + + + name + other + type + vector + + + returnType + vector + tooltip + Subtract vector from vector + + + __unm + + + parameters + + + name + self + type + vector + + + returnType + vector + tooltip + Negate a vector + + + + tooltip + Vector class representing a 3D vector with x, y, z components + + DetectedEvent + + properties + + index + number + valid + boolean + canAdjustDamage + boolean + + methods + + adjustDamage + + + parameters + + + name + self + type + DetectedEvent + + + name + damage + type + number + + + returnType + () + tooltip + Adjusts the damage amount for this detected event + + + getOwner + + + parameters + + + name + self + type + DetectedEvent + + + returnType + any + tooltip + Gets the owner of the detected object + + + getName + + + parameters + + + name + self + type + DetectedEvent + + + returnType + any + tooltip + Gets the name of the detected object + + + getFace + + + parameters + + + name + self + type + DetectedEvent + + + returnType + any + tooltip + Gets the face number of the detected collision/touch + + + getLinkNumber + + + parameters + + + name + self + type + DetectedEvent + + + returnType + any + tooltip + Gets the link number of the detected object + + + getKey + + + parameters + + + name + self + type + DetectedEvent + + + returnType + any + tooltip + Gets the key/UUID of the detected object + + + new + + + parameters + + + name + self + type + DetectedEvent + + + name + index + type + number + + + name + canAdjustDamage + type + boolean + + + returnType + DetectedEvent + tooltip + Creates a new DetectedEvent instance + + + + tooltip + DetectedEvent class for handling multi-event handlers like touch, collision, sensor events + + LLEvents + + properties + + _handlers + { [string]: { EventHandler } } + + methods + + on + + + parameters + + + name + self + type + LLEvents + + + name + event_name + type + string + + + name + handler + type + EventHandler + + + returnType + EventHandler + tooltip + Registers a persistent event handler for the specified event + + + once + + + parameters + + + name + self + type + LLEvents + + + name + event_name + type + string + + + name + handler + type + EventHandler + + + returnType + EventHandler + tooltip + Registers a one-time event handler that will be automatically removed after first execution + + + off + + + parameters + + + name + self + type + LLEvents + + + name + event_name + type + string + + + name + handler + type + EventHandler + optional + 1 + + + returnType + boolean + tooltip + Removes an event handler and returns true if successful + + + listeners + + + parameters + + + name + self + type + LLEvents + + + name + event_name + type + string + + + returnType + { EventHandler } + tooltip + Returns a copy of all handlers registered for the specified event + + + eventNames + + + parameters + + + name + self + type + LLEvents + + + returnType + { string } + tooltip + Returns an array of all event names that have registered handlers + + + + tooltip + LLEvents interface providing dynamic event handler management for Second Life scripts + + LLTimers + + properties + + _timers + { _LLTimerData } + + methods + + on + + + parameters + + + name + self + type + LLTimers + + + name + seconds + type + number + + + name + handler + type + EventHandler + + + returnType + EventHandler + tooltip + Registers a repeating timer that will call the handler every specified number of seconds + + + once + + + parameters + + + name + self + type + LLTimers + + + name + seconds + type + number + + + name + handler + type + EventHandler + + + returnType + EventHandler + tooltip + Registers a one-shot timer that will call the handler once after the specified delay + + + off + + + parameters + + + name + self + type + LLTimers + + + name + handler + type + EventHandler + optional + 1 + + + returnType + boolean + tooltip + Removes a timer handler and returns true if successful + + + + tooltip + LLTimers interface providing timer management for Second Life scripts + + _LLTimerData + + properties + + handler + EventHandler + nextRun + number + interval + number | nil + + tooltip + Internal timer data structure containing handler function and timing information + + + modules + + bit32 + + methods + + arshift + + + parameters + + + name + n + type + integer + + + name + i + type + integer + + + returnType + integer + tooltip + Arithmetic right shift for integers + + + parameters + + + name + n + type + integer | number + + + name + i + type + integer | number + + + returnType + number + tooltip + Arithmetic right shift for mixed types + + + band + + + parameters + + + name + args + type + integer + variadic + 1 + + + returnType + integer + tooltip + Bitwise AND for integers + + + parameters + + + name + args + type + integer | number + variadic + 1 + + + returnType + number + tooltip + Bitwise AND for mixed types + + + bnot + + + parameters + + + name + n + type + integer + + + returnType + integer + tooltip + Bitwise NOT for integers + + + parameters + + + name + n + type + integer | number + + + returnType + number + tooltip + Bitwise NOT for mixed types + + + bor + + + parameters + + + name + args + type + integer + variadic + 1 + + + returnType + integer + tooltip + Bitwise OR for integers + + + parameters + + + name + args + type + integer | number + variadic + 1 + + + returnType + number + tooltip + Bitwise OR for mixed types + + + bxor + + + parameters + + + name + args + type + integer + variadic + 1 + + + returnType + integer + tooltip + Bitwise XOR for integers + + + parameters + + + name + args + type + integer | number + variadic + 1 + + + returnType + number + tooltip + Bitwise XOR for mixed types + + + btest + + + parameters + + + name + args + type + integer | number + variadic + 1 + + + returnType + boolean + tooltip + Test if bitwise AND is non-zero + + + extract + + + parameters + + + name + n + type + integer + + + name + f + type + integer + + + name + w + type + integer + + + returnType + integer + tooltip + Extract bits from integer + + + parameters + + + name + n + type + integer | number + + + name + f + type + integer | number + + + name + w + type + integer | number + + + returnType + number + tooltip + Extract bits from mixed types + + + lrotate + + + parameters + + + name + n + type + integer + + + name + i + type + integer + + + returnType + integer + tooltip + Left rotate for integers + + + parameters + + + name + n + type + integer | number + + + name + i + type + integer | number + + + returnType + number + tooltip + Left rotate for mixed types + + + lshift + + + parameters + + + name + n + type + integer + + + name + i + type + integer + + + returnType + integer + tooltip + Left shift for integers + + + parameters + + + name + n + type + integer | number + + + name + i + type + integer | number + + + returnType + number + tooltip + Left shift for mixed types + + + replace + + + parameters + + + name + n + type + integer + + + name + r + type + integer + + + name + f + type + integer + + + name + w + type + integer + optional + 1 + + + returnType + integer + tooltip + Replace bits in integer + + + parameters + + + name + n + type + integer | number + + + name + r + type + integer | number + + + name + f + type + integer | number + + + name + w + type + integer | number + optional + 1 + + + returnType + number + tooltip + Replace bits in mixed types + + + rrotate + + + parameters + + + name + n + type + integer + + + name + i + type + integer + + + returnType + integer + tooltip + Right rotate for integers + + + parameters + + + name + n + type + integer | number + + + name + i + type + integer | number + + + returnType + number + tooltip + Right rotate for mixed types + + + rshift + + + parameters + + + name + n + type + integer + + + name + i + type + integer + + + returnType + integer + tooltip + Right shift for integers + + + parameters + + + name + n + type + integer | number + + + name + i + type + integer | number + + + returnType + number + tooltip + Right shift for mixed types + + + countlz + + + parameters + + + name + n + type + integer + + + returnType + integer + tooltip + Count leading zeros for integers + + + parameters + + + name + n + type + number + + + returnType + integer + tooltip + Count leading zeros for numbers + + + countrz + + + parameters + + + name + n + type + integer + + + returnType + integer + tooltip + Count trailing zeros for integers + + + parameters + + + name + n + type + number + + + returnType + integer + tooltip + Count trailing zeros for numbers + + + byteswap + + + parameters + + + name + n + type + integer + + + returnType + integer + tooltip + Byte swap for integers + + + parameters + + + name + n + type + number + + + returnType + integer + tooltip + Byte swap for numbers + + + + tooltip + Bitwise operations library providing bit manipulation functions + + vector + + properties + + one + vector + zero + vector + + methods + + abs + + + parameters + + + name + vec + type + vector + + + returnType + vector + tooltip + Applies math.abs to every component of the input vector + + + angle + + + parameters + + + name + vec1 + type + vector + + + name + vec2 + type + vector + + + name + axis + type + vector + optional + 1 + + + returnType + number + tooltip + Computes the angle between two vectors in radians. The axis, if specified, is used to determine the sign of the angle + + + ceil + + + parameters + + + name + vec + type + vector + + + returnType + vector + tooltip + Applies math.ceil to every component of the input vector + + + clamp + + + parameters + + + name + vec + type + vector + + + name + min + type + vector + + + name + max + type + vector + + + returnType + vector + tooltip + Applies math.clamp to every component of the input vector + + + create + + + parameters + + + name + x + type + number | integer + + + name + y + type + number | integer + + + name + z + type + number | integer + + + returnType + vector + tooltip + Creates a new vector with the given component values + + + cross + + + parameters + + + name + vec1 + type + vector + + + name + vec2 + type + vector + + + returnType + vector + tooltip + Computes the cross product of two vectors + + + dot + + + parameters + + + name + vec1 + type + vector + + + name + vec2 + type + vector + + + returnType + number + tooltip + Computes the dot product of two vectors + + + floor + + + parameters + + + name + vec + type + vector + + + returnType + vector + tooltip + Applies math.floor to every component of the input vector + + + magnitude + + + parameters + + + name + vec + type + vector + + + returnType + number + tooltip + Calculates the magnitude of a given vector + + + max + + + parameters + + + name + args + type + vector + variadic + 1 + + + returnType + vector + tooltip + Applies math.max to the corresponding components of the input vectors + + + min + + + parameters + + + name + args + type + vector + variadic + 1 + + + returnType + vector + tooltip + Applies math.min to the corresponding components of the input vectors + + + normalize + + + parameters + + + name + vec + type + vector + + + returnType + vector + tooltip + Computes the normalized version (unit vector) of a given vector + + + sign + + + parameters + + + name + vec + type + vector + + + returnType + vector + tooltip + Applies math.sign to every component of the input vector + + + + tooltip + Vector utility functions for operations on vectors + + lljson + + properties + + empty_array + lljson_constant + null + lljson_constant + + methods + + decode + + + parameters + + + name + json + type + string + + + returnType + string | number | integer | vector | uuid | quaternion | boolean | table | nil + tooltip + Decode JSON string to Lua value + + + encode + + + parameters + + + name + value + type + string | number | integer | vector | uuid | quaternion | boolean | table | nil + + + returnType + string + tooltip + Encode Lua value as JSON + + + + tooltip + JSON encoding and decoding module with constants for null and empty arrays + + llbase64 + + methods + + decode + + + parameters + + + name + base64 + type + string + + + returnType + string + tooltip + Decode a base64 string to a string + + + parameters + + + name + base64 + type + string + + + name + asBuffer + type + true + + + returnType + buffer + tooltip + Decode a base64 string to a buffer + + + parameters + + + name + base64 + type + string + + + name + asBuffer + type + false + + + returnType + string + tooltip + Decode a base64 string to a string + + + encode + + + parameters + + + name + value + type + string | buffer + + + returnType + string + tooltip + Encode a string or buffer to base64 + + + + tooltip + Base64 encoding and decoding module for strings and buffers + + + + diff --git a/indra/newview/gltf/accessor.cpp b/indra/newview/gltf/accessor.cpp index 03f7331893f..f0ad3fa5944 100644 --- a/indra/newview/gltf/accessor.cpp +++ b/indra/newview/gltf/accessor.cpp @@ -158,6 +158,11 @@ bool Buffer::prep(Asset& asset) { std::string dir = gDirUtilp->getDirName(asset.mFilename); std::string bin_file = dir + gDirUtilp->getDirDelimiter() + mUri; + if (!gDirUtilp->fileExists(bin_file)) + { + // Characters might be escaped in the URI + bin_file = dir + gDirUtilp->getDirDelimiter() + LLURI::unescape(mUri); + } llifstream file(bin_file.c_str(), std::ios::binary); if (!file.is_open()) diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp index e24aea4a28c..28f30ae1c97 100644 --- a/indra/newview/gltf/asset.cpp +++ b/indra/newview/gltf/asset.cpp @@ -589,7 +589,9 @@ bool Asset::prep() for (U32 variant = 0; variant < LLGLSLShader::NUM_GLTF_VARIANTS; ++variant) { +#ifdef SHOW_ASSERT U32 attribute_mask = 0; +#endif // for each mesh for (auto& mesh : mMeshes) { @@ -607,7 +609,9 @@ bool Asset::prep() // all primitives of a given variant and material should all have the same attribute mask llassert(attribute_mask == 0 || primitive.mAttributeMask == attribute_mask); +#ifdef SHOW_ASSERT attribute_mask |= primitive.mAttributeMask; +#endif } } } diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp index dd1d3276833..4f8f80129d9 100644 --- a/indra/newview/gltf/llgltfloader.cpp +++ b/indra/newview/gltf/llgltfloader.cpp @@ -412,17 +412,14 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map // Process this node's mesh if it has one if (node.mMesh >= 0 && node.mMesh < mGLTFAsset.mMeshes.size()) { - LLMatrix4 transformation; - material_map mats; - - LLModel* pModel = new LLModel(volume_params, 0.f); - const LL::GLTF::Mesh& mesh = mGLTFAsset.mMeshes[node.mMesh]; - - // Get base mesh name and track usage - std::string base_name = getLodlessLabel(mesh); + // Get base node name and track usage + // Potentially multiple nodes can reuse the same mesh and Collada used + // node name instead of mesh name, so for consistency use node name if + // avaliable, node index otherwise. + std::string base_name = getLodlessLabel(node); if (base_name.empty()) { - base_name = "mesh_" + std::to_string(node.mMesh); + base_name = "node_" + std::to_string(node_idx); } S32 instance_count = mesh_name_counts[base_name]++; @@ -433,6 +430,12 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map base_name = base_name + "_copy_" + std::to_string(instance_count); } + LLMatrix4 transformation; + material_map mats; + + LLModel* pModel = new LLModel(volume_params, 0.f); + const LL::GLTF::Mesh& mesh = mGLTFAsset.mMeshes[node.mMesh]; + if (populateModelFromMesh(pModel, base_name, mesh, node, mats) && (LLModel::NO_ERRORS == pModel->getStatus()) && validate_model(pModel)) @@ -652,6 +655,14 @@ std::string LLGLTFLoader::processTexture(S32 texture_index, const std::string& t filename = filename.substr(pos + 1); } + std::string dir = gDirUtilp->getDirName(mFilename); + std::string full_path = dir + gDirUtilp->getDirDelimiter() + filename; + if (!gDirUtilp->fileExists(full_path) && filename.find("data:") == std::string::npos) + { + // Uri might be escaped + filename = LLURI::unescape(filename); + } + LL_INFOS("GLTF_IMPORT") << "Found texture: " << filename << " for material: " << material_name << LL_ENDL; LLSD args; @@ -1810,13 +1821,13 @@ size_t LLGLTFLoader::getSuffixPosition(const std::string &label) return -1; } -std::string LLGLTFLoader::getLodlessLabel(const LL::GLTF::Mesh& mesh) +std::string LLGLTFLoader::getLodlessLabel(const LL::GLTF::Node& node) { - size_t ext_pos = getSuffixPosition(mesh.mName); + size_t ext_pos = getSuffixPosition(node.mName); if (ext_pos != -1) { - return mesh.mName.substr(0, ext_pos); + return node.mName.substr(0, ext_pos); } - return mesh.mName; + return node.mName; } diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h index e8b91996c78..7aa1a94c201 100644 --- a/indra/newview/gltf/llgltfloader.h +++ b/indra/newview/gltf/llgltfloader.h @@ -170,7 +170,7 @@ class LLGLTFLoader : public LLModelLoader void notifyUnsupportedExtension(bool unsupported); static size_t getSuffixPosition(const std::string& label); - static std::string getLodlessLabel(const LL::GLTF::Mesh& mesh); + static std::string getLodlessLabel(const LL::GLTF::Node& mesh); // bool mPreprocessGLTF; diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 77f24ac6a68..0e366980185 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -163,6 +163,74 @@ Var DO_UNINSTALL_V2 # If non-null, path to a previous Viewer 2 installation !include 'LogicLib.nsh' # for value comparison !include "x64.nsh" # for 64bit detection +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Substring function +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +!define StrStr "!insertmacro StrStr" + +!macro StrStr ResultVar String SubString + Push `${String}` + Push `${SubString}` + Call StrStr + Pop `${ResultVar}` +!macroend + +Function StrStr + +# After this point: +# ------------------------------------------ +# $R0 = SubString (input) +# $R1 = String (input) +# $R2 = SubStringLen (temp) +# $R3 = StrLen (temp) +# $R4 = StartCharPos (temp) +# $R5 = TempStr (temp) +# function from nsis.sourceforge.io/StrStr + + ;Get input from user + Exch $R0 + Exch + Exch $R1 + Push $R2 + Push $R3 + Push $R4 + Push $R5 + + ;Get "String" and "SubString" length + StrLen $R2 $R0 + StrLen $R3 $R1 + ;Start "StartCharPos" counter + StrCpy $R4 0 + + ;Loop until "SubString" is found or "String" reaches its end + ${Do} + ;Remove everything before and after the searched part ("TempStr") + StrCpy $R5 $R1 $R2 $R4 + + ;Compare "TempStr" with "SubString" + ${IfThen} $R5 == $R0 ${|} ${ExitDo} ${|} + ;If not "SubString", this could be "String"'s end + ${IfThen} $R4 >= $R3 ${|} ${ExitDo} ${|} + ;If not, continue the loop + IntOp $R4 $R4 + 1 + ${Loop} + +# After this point: +# ------------------------------------------ +# $R0 = ResultVar (output) + + ;Remove part before "SubString" on "String" (if there has one) + StrCpy $R0 $R1 `` $R4 + + ;Return output to user + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Pop $R1 + Exch $R0 +FunctionEnd + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Pre-directory page callback ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -190,15 +258,31 @@ Function .onInit # However, SL-10506 complains about the resulting behavior, so the logic below # is adapted from before we introduced MultiUser.nsh. +# Check if user specified /D= on the command line +System::Call 'kernel32::GetCommandLine()t .r0' +Push $0 +Push " /D=" +Call StrStr +Pop $1 +${If} $1 != "" + # /D= was specified, extract the path + # spaces are allowed in path after /D=, it's expected to be the last parameter + StrLen $2 $1 + StrCpy $INSTDIR $1 $2 4 # Skip over " /D=" + Goto after_instdir +${EndIf} + # if $0 is empty, this is the first time for this viewer name ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" "" # viewer with this name was installed before ${If} $0 != "" - # use the value we got from registry as install location + # use the value we got from registry as install location StrCpy $INSTDIR $0 ${EndIf} +after_instdir: + Call CheckCPUFlags # Make sure we have SSE2 support Call CheckWindowsVersion # Don't install On unsupported systems Push $0 diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 339656089c8..b2c66b1bace 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1752,7 +1752,6 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor() LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(bool *hit_limit) { // Compute base camera position and look-at points. - F32 camera_land_height; LLVector3d frame_center_global = !isAgentAvatarValid() ? gAgent.getPositionGlobal() : gAgent.getPosGlobalFromAgent(getAvatarRootPosition()); @@ -1989,10 +1988,11 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(bool *hit_limit) } } - // Don't let camera go underground - F32 camera_min_off_ground = getCameraMinOffGround(); - camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global); - F32 minZ = llmax(F_ALMOST_ZERO, camera_land_height + camera_min_off_ground); + // Don't let camera go underground if constrained + // If not constrained, permit going 1000m below 0, use case: retrieving objects + F32 camera_min_off_ground = getCameraMinOffGround(); // checks isDisableCameraConstraints + F32 camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global); + F32 minZ = camera_land_height + camera_min_off_ground; if (camera_position_global.mdV[VZ] < minZ) { camera_position_global.mdV[VZ] = minZ; diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 25f5cbd78fc..a075b6f004d 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -538,6 +538,27 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::ETyp return item; } +const S32 LLAgentWearables::getWearableIdxFromItem(const LLViewerInventoryItem* item) const +{ + if (!item) return -1; + if (!item->isWearableType()) return -1; + + LLWearableType::EType type = item->getWearableType(); + U32 wearable_count = getWearableCount(type); + if (0 == wearable_count) return -1; + + const LLUUID& asset_id = item->getAssetUUID(); + + for (U32 i = 0; i < wearable_count; ++i) + { + const LLViewerWearable* wearable = getViewerWearable(type, i); + if (!wearable) continue; + if (wearable->getAssetID() != asset_id) continue; + return i; + } + + return -1; +} const LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const { const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id); @@ -1471,7 +1492,7 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos LLWearableType::EType type = item->getWearableType(); U32 wearable_count = getWearableCount(type); - if (0 == wearable_count) return false; + if (wearable_count < 2) return false; const LLUUID& asset_id = item->getAssetUUID(); diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 3b8ff93c76c..1e118ffa98a 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -87,6 +87,7 @@ class LLAgentWearables : public LLInitClass, public LLWearable public: const LLUUID getWearableItemID(LLWearableType::EType type, U32 index /*= 0*/) const; const LLUUID getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const; + const S32 getWearableIdxFromItem(const LLViewerInventoryItem* item) const; const LLViewerWearable* getWearableFromItemID(const LLUUID& item_id) const; LLViewerWearable* getWearableFromItemID(const LLUUID& item_id); LLViewerWearable* getWearableFromAssetID(const LLUUID& asset_id); diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index d4b05dde72f..b8fd3dc189f 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -372,7 +372,7 @@ @implementation LLApplication - (void)sendEvent:(NSEvent *)event { [super sendEvent:event]; - if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) + if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) { [[self keyWindow] sendEvent:event]; } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6fa23727b1c..0d57b33a516 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1500,6 +1500,27 @@ void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false) } } +bool needs_to_replace(LLViewerInventoryItem* item_to_wear, bool & first_for_object, std::vector& first_for_type, bool replace) +{ + bool res = false; + LLAssetType::EType type = item_to_wear->getType(); + if (type == LLAssetType::AT_OBJECT) + { + res = first_for_object && replace; + first_for_object = false; + } + else if (type == LLAssetType::AT_CLOTHING) + { + LLWearableType::EType wtype = item_to_wear->getWearableType(); + if (wtype >= 0 && wtype < LLWearableType::WT_COUNT) + { + res = first_for_type[wtype] && replace; + first_for_type[wtype] = false; + } + } + return res; +} + void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, bool do_update, bool replace, @@ -1508,7 +1529,8 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, LL_DEBUGS("UIUsage") << "wearItemsOnAvatar" << LL_ENDL; LLUIUsage::instance().logCommand("Avatar.WearItem"); - bool first = true; + bool first_for_object = true; + std::vector first_for_type(LLWearableType::WT_COUNT, true); LLInventoryObject::const_object_list_t items_to_link; @@ -1516,9 +1538,6 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, it != item_ids_to_wear.end(); ++it) { - replace = first && replace; - first = false; - const LLUUID& item_id_to_wear = *it; if (item_id_to_wear.isNull()) @@ -1537,8 +1556,9 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) { LL_DEBUGS("Avatar") << "inventory item in library, will copy and wear " - << item_to_wear->getName() << " id " << item_id_to_wear << LL_ENDL; - LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace)); + << item_to_wear->getName() << " id " << item_id_to_wear << LL_ENDL; + bool replace_item = needs_to_replace(item_to_wear, first_for_object, first_for_type, replace); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb, _1, replace_item)); copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb); continue; @@ -1576,7 +1596,8 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, } LLWearableType::EType type = item_to_wear->getWearableType(); S32 wearable_count = gAgentWearables.getWearableCount(type); - if ((replace && wearable_count != 0) || !gAgentWearables.canAddWearable(type)) + bool replace_item = needs_to_replace(item_to_wear, first_for_object, first_for_type, replace); + if ((replace_item && wearable_count != 0) || !gAgentWearables.canAddWearable(type)) { LLUUID item_id = gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1); @@ -1605,7 +1626,13 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, case LLAssetType::AT_OBJECT: { - rez_attachment(item_to_wear, NULL, replace); + // Note that this will replace only first attachment regardless of attachment point, + // so if user is wearing two items over other two on different attachment points, + // only one will be replaced. + // Unfortunately we have no way to determine attachment point from inventory item. + // We might want to forbid wearing multiple objects with replace option in future. + bool replace_item = needs_to_replace(item_to_wear, first_for_object, first_for_type, replace); + rez_attachment(item_to_wear, NULL, replace_item); } break; @@ -4218,37 +4245,54 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b if (item->getType() != LLAssetType::AT_CLOTHING) return false; if (!gInventory.isObjectDescendentOf(item->getUUID(), getCOF())) return false; + S32 pos = gAgentWearables.getWearableIdxFromItem(item); + if (pos < 0) return false; // Not found + + U32 count = gAgentWearables.getWearableCount(item->getWearableType()); + if (count < 2) return false; // Nothing to swap with + if (closer_to_body) + { + if (pos == 0) return false; // already first + } + else + { + if (pos == count - 1) return false; // already last + } + + U32 old_pos = (U32)pos; + U32 swap_with = closer_to_body ? old_pos - 1 : old_pos + 1; + LLUUID swap_item_id = gAgentWearables.getWearableItemID(item->getWearableType(), swap_with); + + // Find link item from item id. LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLFindWearablesOfType filter_wearables_of_type(item->getWearableType()); gInventory.collectDescendentsIf(getCOF(), cats, items, true, filter_wearables_of_type); if (items.empty()) return false; - // We assume that the items have valid descriptions. - std::sort(items.begin(), items.end(), WearablesOrderComparator(item->getWearableType())); - - if (closer_to_body && items.front() == item) return false; - if (!closer_to_body && items.back() == item) return false; - - LLInventoryModel::item_array_t::iterator it = std::find(items.begin(), items.end(), item); - if (items.end() == it) return false; - - - //swapping descriptions - closer_to_body ? --it : ++it; - LLViewerInventoryItem* swap_item = *it; - if (!swap_item) return false; - std::string tmp = swap_item->getActualDescription(); - swap_item->setDescription(item->getActualDescription()); - item->setDescription(tmp); + LLViewerInventoryItem* swap_item = nullptr; + for (auto iter : items) + { + if (iter->getLinkedUUID() == swap_item_id) + { + swap_item = iter.get(); + break; + } + } + if (!swap_item) + { + return false; + } - // LL_DEBUGS("Inventory") << "swap, item " - // << ll_pretty_print_sd(item->asLLSD()) - // << " swap_item " - // << ll_pretty_print_sd(swap_item->asLLSD()) << LL_ENDL; + // Description is supposed to hold sort index, but user could have changed + // order rapidly and there might be a state mismatch between description + // and gAgentWearables, trust gAgentWearables over description. + // Generate new description. + std::string new_desc = build_order_string(item->getWearableType(), old_pos); + swap_item->setDescription(new_desc); + new_desc = build_order_string(item->getWearableType(), swap_with); + item->setDescription(new_desc); - // FIXME switch to use AISv3 where supported. - //items need to be updated on a dataserver item->setComplete(true); item->updateServer(false); gInventory.updateItem(item); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 66dadf75450..d0d55591c27 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -109,6 +109,7 @@ #include "lllocalbitmaps.h" #include "llperfstats.h" #include "llgltfmateriallist.h" +#include "llwebsocketmgr.h" // Linden library includes #include "llavatarnamecache.h" @@ -993,6 +994,7 @@ bool LLAppViewer::init() return false; } +#if defined(LL_X86) || defined(LL_X86_64) // Without SSE2 support we will crash almost immediately, warn here. if (!gSysCPU.hasSSE2()) { @@ -1004,6 +1006,7 @@ bool LLAppViewer::init() // quit immediately return false; } +#endif // alert the user if they are using unsupported hardware if (!gSavedSettings.getBOOL("AlertedUnsupportedHardware")) @@ -1263,6 +1266,7 @@ bool LLAppViewer::init() LLViewerCamera::createInstance(); LL::GLTFSceneManager::createInstance(); + gSavedSettings.setU32("DebugQualityPerformance", gSavedSettings.getU32("RenderQualityPerformance")); #if LL_WINDOWS if (!mSecondInstance) @@ -1289,7 +1293,7 @@ void LLAppViewer::initMaxHeapSize() //------------------------------------------------------------------------------------------ //currently SL is built under 32-bit setting, we set its max heap size no more than 1.6 GB. - #ifndef LL_X86_64 + #if !defined(LL_X86_64) && !defined(LL_ARM64) F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ; #else F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize64"); @@ -1352,6 +1356,7 @@ bool LLAppViewer::doFrame() #endif LL_RECORD_BLOCK_TIME(FTM_FRAME); + LL_PROFILE_GPU_ZONE("Frame"); { // and now adjust the visuals from previous frame. if(LLPerfStats::tunables.userAutoTuneEnabled && LLPerfStats::tunables.tuningFlag != LLPerfStats::Tunables::Nothing) @@ -1441,24 +1446,26 @@ bool LLAppViewer::doFrame() if (!LLApp::isExiting()) { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df JoystickKeyboard"); - pingMainloopTimeout("Main:JoystickKeyboard"); - - // Scan keyboard for movement keys. Command keys and typing - // are handled by windows callbacks. Don't do this until we're - // done initializing. JC - if (gViewerWindow - && (gHeadlessClient || gViewerWindow->getWindow()->getVisible()) - && gViewerWindow->getActive() - && !gViewerWindow->getWindow()->getMinimized() - && LLStartUp::getStartupState() == STATE_STARTED - && (gHeadlessClient || !gViewerWindow->getShowProgress()) - && !gFocusMgr.focusLocked()) { - LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); - joystick->scanJoystick(); - gKeyboard->scanKeyboard(); - gViewerInput.scanMouse(); + LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df JoystickKeyboard"); + pingMainloopTimeout("Main:JoystickKeyboard"); + + // Scan keyboard for movement keys. Command keys and typing + // are handled by windows callbacks. Don't do this until we're + // done initializing. JC + if (gViewerWindow + && (gHeadlessClient || gViewerWindow->getWindow()->getVisible()) + && gViewerWindow->getActive() + && !gViewerWindow->getWindow()->getMinimized() + && LLStartUp::getStartupState() == STATE_STARTED + && (gHeadlessClient || !gViewerWindow->getShowProgress()) + && !gFocusMgr.focusLocked()) + { + LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE); + joystick->scanJoystick(); + gKeyboard->scanKeyboard(); + gViewerInput.scanMouse(); + } } // Update state based on messages, user input, object idle. @@ -3167,17 +3174,6 @@ bool LLAppViewer::initWindow() LLNotificationsUI::LLNotificationManager::getInstance(); - -#ifdef LL_DARWIN - //Satisfy both MAINT-3135 (OSX 10.6 and earlier) MAINT-3288 (OSX 10.7 and later) - LLOSInfo& os_info = LLOSInfo::instance(); - if (os_info.mMajorVer == 10 && os_info.mMinorVer < 7) - { - if ( os_info.mMinorVer == 6 && os_info.mBuild < 8 ) - gViewerWindow->getWindow()->setOldResize(true); - } -#endif - if (gSavedSettings.getBOOL("WindowMaximized")) { gViewerWindow->getWindow()->maximize(); @@ -3292,6 +3288,11 @@ LLSD LLAppViewer::getViewerInfo() const info["VIEWER_VERSION_STR"] = versionInfo.getVersion(); info["CHANNEL"] = versionInfo.getChannel(); info["ADDRESS_SIZE"] = ADDRESS_SIZE; +#if LL_ARM64 + info["ARCHITECTURE"] = "ARM"; +#else + info["ARCHITECTURE"] = "x86"; +#endif std::string build_config = versionInfo.getBuildConfig(); if (build_config != "Release") { @@ -3383,7 +3384,7 @@ LLSD LLAppViewer::getViewerInfo() const info["FONT_SIZE_ADJUSTMENT"] = gSavedSettings.getF32("FontScreenDPI"); info["UI_SCALE"] = gSavedSettings.getF32("UIScaleFactor"); info["DRAW_DISTANCE"] = gSavedSettings.getF32("RenderFarClip"); - info["NET_BANDWITH"] = gSavedSettings.getF32("ThrottleBandwidthKBPS"); + info["NET_BANDWITH"] = LLViewerThrottle::getMaxBandwidthKbps(); info["LOD_FACTOR"] = gSavedSettings.getF32("RenderVolumeLODFactor"); info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance"); info["TEXTURE_MEMORY"] = LLSD::Integer(gGLManager.mVRAM); @@ -3945,8 +3946,15 @@ void LLAppViewer::processMarkerFiles() else if (marker_is_same_version) { // the file existed, is ours, and matched our version, so we can report on what it says - LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL; + LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed or froze" << LL_ENDL; +#if LL_WINDOWS && LL_BUGSPLAT + // bugsplat will set correct state in bugsplatSendLog + // Might be more accurate to rename this one into 'unknown' + gLastExecEvent = LAST_EXEC_FROZE; +#else gLastExecEvent = LAST_EXEC_OTHER_CRASH; +#endif // LL_WINDOWS + } else { @@ -4195,7 +4203,7 @@ void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions) // case where we need the viewer to exit without any need for notifications void LLAppViewer::earlyExitNoNotify() { - LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL; + LL_WARNS() << "app_early_exit with no notification." << LL_ENDL; gDoDisconnect = true; finish_early_exit( LLSD(), LLSD() ); } @@ -4426,6 +4434,9 @@ bool LLAppViewer::initCache() const U32 CACHE_NUMBER_OF_REGIONS_FOR_OBJECTS = 128; LLVOCache::getInstance()->initCache(LL_PATH_CACHE, CACHE_NUMBER_OF_REGIONS_FOR_OBJECTS, getObjectCacheVersion()); + // Remove old, stale CEF cache folders + purgeCefStaleCaches(); + return true; } @@ -4450,18 +4461,28 @@ void LLAppViewer::loadKeyBindings() LLUrlRegistry::instance().setKeybindingHandler(&gViewerInput); } +// As per GHI #4498, remove old, stale CEF cache folders from previous sessions +void LLAppViewer::purgeCefStaleCaches() +{ + // TODO: we really shouldn't use a hard coded name for the cache folder here... + const std::string browser_parent_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache"); + if (LLFile::isdir(browser_parent_cache)) + { + // This is a sledgehammer approach - nukes the cef_cache dir entirely + // which is then recreated the first time a CEF instance creates an + // individual cache folder. If we ever decide to retain some folders + // e.g. Search UI cache - then we will need a more granular approach. + gDirUtilp->deleteDirAndContents(browser_parent_cache); + } +} + void LLAppViewer::purgeCache() { LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL; LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE); LLVOCache::getInstance()->removeCache(LL_PATH_CACHE); LLViewerShaderMgr::instance()->clearShaderCache(); - std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache"); - if (LLFile::isdir(browser_cache)) - { - // cef does not support clear_cache and clear_cookies, so clear what we can manually. - gDirUtilp->deleteDirAndContents(browser_cache); - } + purgeCefStaleCaches(); gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*"); } @@ -4530,6 +4551,7 @@ void LLAppViewer::forceDisconnect(const std::string& mesg) } else { + sendSimpleLogoutRequest(); args["MESSAGE"] = big_reason; LLNotificationsUtil::add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect ); } @@ -4742,6 +4764,11 @@ void LLAppViewer::idle() LLMortician::updateClass(); LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() LLDirPickerThread::clearDead(); + + if (LLWebsocketMgr::instanceExists()) + { + LLWebsocketMgr::instance().update(); + } F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); LLGLTFMaterialList::flushUpdates(); @@ -5310,6 +5337,27 @@ void LLAppViewer::sendLogoutRequest() } } +void LLAppViewer::sendSimpleLogoutRequest() +{ + if (!mLogoutRequestSent && gMessageSystem) + { + gLogoutInProgress = true; + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_LogoutRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + + LL_INFOS("Agent") << "Logging out as agent: " << gAgent.getID() << " Session: " << gAgent.getSessionID() << LL_ENDL; + + gLogoutTimer.reset(); + gLogoutMaxTime = LOGOUT_REQUEST_TIME; + mLogoutRequestSent = true; + } +} + void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp) { if (!regionp || !regionp->capabilitiesReceived()) @@ -5374,6 +5422,12 @@ void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const } } +bool LLAppViewer::errorMarkerExists() const +{ + std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); + return LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB); +} + void LLAppViewer::outOfMemorySoftQuit() { if (!mQuitRequested) @@ -5505,7 +5559,10 @@ void LLAppViewer::idleNetwork() add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); // Retransmit unacknowledged packets. - gXferManager->retransmitUnackedPackets(); + if (gXferManager) + { + gXferManager->retransmitUnackedPackets(); + } gAssetStorage->checkForTimeouts(); gViewerThrottle.setBufferLoadRate(gMessageSystem->getBufferLoadRate()); gViewerThrottle.updateDynamicThrottle(); @@ -5625,7 +5682,11 @@ void LLAppViewer::forceErrorBreakpoint() #ifdef LL_WINDOWS DebugBreak(); #else +#if defined(LL_X86) || defined(LL_X86_64) asm ("int $3"); +#else + __builtin_trap(); +#endif #endif return; } @@ -5929,100 +5990,21 @@ void LLAppViewer::initDiscordSocial() gDiscordPartyMaxSize = 0; gDiscordTimestampsStart = time(nullptr); gDiscordClient = std::make_shared(); - gDiscordClient->SetStatusChangedCallback([](discordpp::Client::Status status, discordpp::Client::Error, int32_t) { - if (status == discordpp::Client::Status::Ready) - { - updateDiscordActivity(); - } - }); - if (gSavedSettings.getBOOL("EnableDiscord")) - { - auto credential = gSecAPIHandler->loadCredential("Discord"); - if (credential.notNull()) - { - gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) { - if (result.Successful()) - gDiscordClient->Connect(); - else - LL_WARNS("Discord") << result.Error() << LL_ENDL; - }); - } - else - { - LL_WARNS("Discord") << "Integration was enabled, but no credentials. Disabling integration." << LL_ENDL; - gSavedSettings.setBOOL("EnableDiscord", false); - } - } + gDiscordClient->SetApplicationId(1394782217405862001); + updateDiscordActivity(); } -void LLAppViewer::toggleDiscordIntegration(const LLSD& value) +void LLAppViewer::updateDiscordActivity() { - static const uint64_t APPLICATION_ID = 1394782217405862001; - if (value.asBoolean()) - { - discordpp::AuthorizationArgs args{}; - args.SetClientId(APPLICATION_ID); - args.SetScopes(discordpp::Client::GetDefaultPresenceScopes()); - auto codeVerifier = gDiscordClient->CreateAuthorizationCodeVerifier(); - args.SetCodeChallenge(codeVerifier.Challenge()); - gDiscordClient->Authorize(args, [codeVerifier](auto result, auto code, auto redirectUri) { - if (result.Successful()) - { - gDiscordClient->GetToken(APPLICATION_ID, code, codeVerifier.Verifier(), redirectUri, [](discordpp::ClientResult result, std::string accessToken, std::string, discordpp::AuthorizationTokenType, int32_t, std::string) { - if (result.Successful()) - { - gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, accessToken, [accessToken](discordpp::ClientResult result) { - if (result.Successful()) - { - LLSD authenticator = LLSD::emptyMap(); - authenticator["token"] = accessToken; - gSecAPIHandler->saveCredential(gSecAPIHandler->createCredential("Discord", LLSD::emptyMap(), authenticator), true); - gDiscordClient->Connect(); - } - else - { - LL_WARNS("Discord") << result.Error() << LL_ENDL; - } - }); - } - else - { - LL_WARNS("Discord") << result.Error() << LL_ENDL; - } - }); - } - else - { - LL_WARNS("Discord") << result.Error() << LL_ENDL; - gSavedSettings.setBOOL("EnableDiscord", false); - } - }); - } - else + LL_PROFILE_ZONE_SCOPED; + + static LLCachedControl integration_enabled(gSavedSettings, "EnableDiscord", true); + if (!integration_enabled) { - gDiscordClient->Disconnect(); - auto credential = gSecAPIHandler->loadCredential("Discord"); - if (credential.notNull()) - { - gDiscordClient->RevokeToken(APPLICATION_ID, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) { - if (result.Successful()) - LL_INFOS("Discord") << "Access token successfully revoked." << LL_ENDL; - else - LL_WARNS("Discord") << "No access token to revoke." << LL_ENDL; - }); - auto cred = new LLCredential("Discord"); - gSecAPIHandler->deleteCredential(cred); - } - else - { - LL_WARNS("Discord") << "Credentials are already nonexistent." << LL_ENDL; - } + gDiscordClient->ClearRichPresence(); + return; } -} -void LLAppViewer::updateDiscordActivity() -{ - LL_PROFILE_ZONE_SCOPED; discordpp::Activity activity; activity.SetType(discordpp::ActivityTypes::Playing); discordpp::ActivityTimestamps timestamps; @@ -6050,37 +6032,39 @@ void LLAppViewer::updateDiscordActivity() activity.SetDetails(gDiscordActivityDetails); } + auto agent_pos_region = gAgent.getPositionAgent(); + S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f); + S32 pos_y = S32(agent_pos_region.mV[VY] + 0.5f); + S32 pos_z = S32(agent_pos_region.mV[VZ] + 0.5f); + F32 velocity_mag_sq = gAgent.getVelocity().magVecSquared(); + const F32 FLY_CUTOFF = 6.f; + const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF; + const F32 WALK_CUTOFF = 1.5f; + const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF; + if (velocity_mag_sq > FLY_CUTOFF_SQ) + { + pos_x -= pos_x % 4; + pos_y -= pos_y % 4; + } + else if (velocity_mag_sq > WALK_CUTOFF_SQ) + { + pos_x -= pos_x % 2; + pos_y -= pos_y % 2; + } + + std::string location = "Hidden Region"; static LLCachedControl show_state(gSavedSettings, "ShowDiscordActivityState", false); if (show_state) { - auto agent_pos_region = gAgent.getPositionAgent(); - S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f); - S32 pos_y = S32(agent_pos_region.mV[VY] + 0.5f); - S32 pos_z = S32(agent_pos_region.mV[VZ] + 0.5f); - F32 velocity_mag_sq = gAgent.getVelocity().magVecSquared(); - const F32 FLY_CUTOFF = 6.f; - const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF; - const F32 WALK_CUTOFF = 1.5f; - const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF; - if (velocity_mag_sq > FLY_CUTOFF_SQ) - { - pos_x -= pos_x % 4; - pos_y -= pos_y % 4; - } - else if (velocity_mag_sq > WALK_CUTOFF_SQ) - { - pos_x -= pos_x % 2; - pos_y -= pos_y % 2; - } - auto location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z); - activity.SetState(location); - - discordpp::ActivityParty party; - party.SetId(location); - party.SetCurrentSize(gDiscordPartyCurrentSize); - party.SetMaxSize(gDiscordPartyMaxSize); - activity.SetParty(party); + location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z); } + activity.SetState(location); + + discordpp::ActivityParty party; + party.SetId(location); + party.SetCurrentSize(gDiscordPartyCurrentSize); + party.SetMaxSize(gDiscordPartyMaxSize); + activity.SetParty(party); gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {}); } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 14e96afe94a..4f2583cb164 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -149,6 +149,12 @@ class LLAppViewer : public LLApp std::string getWindowTitle() const; // The window display name. void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user. + + // sendSimpleLogoutRequest does not create a marker file. + // Meant for lost network case, and for forced shutdowns, + // to at least attempt to remove the ghost from the world. + void sendSimpleLogoutRequest(); + void badNetworkHandler(); // Cause a crash state due to bad network packet. bool hasSavedFinalSnapshot() { return mSavedFinalSnapshot; } @@ -220,6 +226,7 @@ class LLAppViewer : public LLApp void initGeneralThread(); void purgeUserDataOnExit() { mPurgeUserDataOnExit = true; } + void purgeCefStaleCaches(); // Remove old, stale CEF cache folders void purgeCache(); // Clear the local cache. void purgeCacheImmediate(); //clear local cache immediately. S32 updateTextureThreads(F32 max_time); @@ -244,6 +251,7 @@ class LLAppViewer : public LLApp // Writes an error code into the error_marker file for use on next startup. void createErrorMarker(eLastExecEvent error_code) const; + bool errorMarkerExists() const; // Attempt a 'soft' quit with disconnect and saving of settings/cache. // Intended to be thread safe. @@ -253,7 +261,6 @@ class LLAppViewer : public LLApp #ifdef LL_DISCORD static void initDiscordSocial(); - static void toggleDiscordIntegration(const LLSD& value); static void updateDiscordActivity(); static void updateDiscordPartyCurrentSize(int32_t size); static void updateDiscordPartyMaxSize(int32_t size); diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 17099701560..89d19d180b5 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -73,6 +73,11 @@ static void exceptionTerminateHandler() int main( int argc, char **argv ) { + // Call Tracy first thing to have it allocate memory + // https://github.com/wolfpld/tracy/issues/196 + LL_PROFILER_FRAME_END; + LL_PROFILER_SET_THREAD_NAME("App"); + gArgC = argc; gArgV = argv; diff --git a/indra/newview/llappviewermacosx-objc.h b/indra/newview/llappviewermacosx-objc.h index d0ae0a7fc2f..3fbf4202f1a 100644 --- a/indra/newview/llappviewermacosx-objc.h +++ b/indra/newview/llappviewermacosx-objc.h @@ -30,9 +30,6 @@ #include #include -//Why? Because BOOL -void launchApplication(const std::string* app_name, const std::vector* args); - void force_ns_sxeption(); #endif // LL_LLAPPVIEWERMACOSX_OBJC_H diff --git a/indra/newview/llappviewermacosx-objc.mm b/indra/newview/llappviewermacosx-objc.mm index 9b6bfe621b6..2ea3f2f1713 100644 --- a/indra/newview/llappviewermacosx-objc.mm +++ b/indra/newview/llappviewermacosx-objc.mm @@ -33,45 +33,6 @@ #include "llappviewermacosx-objc.h" -void launchApplication(const std::string* app_name, const std::vector* args) -{ - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - if (app_name->empty()) return; - - NSMutableString* app_name_ns = [NSMutableString stringWithString:[[NSBundle mainBundle] resourcePath]]; //Path to resource dir - [app_name_ns appendFormat:@"/%@", [NSString stringWithCString:app_name->c_str() - encoding:[NSString defaultCStringEncoding]]]; - - NSMutableArray *args_ns = nil; - args_ns = [[NSMutableArray alloc] init]; - - for (int i=0; i < args->size(); ++i) - { - NSLog(@"Adding string %s", (*args)[i].c_str()); - [args_ns addObject: - [NSString stringWithCString:(*args)[i].c_str() - encoding:[NSString defaultCStringEncoding]]]; - } - - NSTask *task = [[NSTask alloc] init]; - NSBundle *bundle = [NSBundle bundleWithPath:[[NSWorkspace sharedWorkspace] fullPathForApplication:app_name_ns]]; - [task setLaunchPath:[bundle executablePath]]; - [task setArguments:args_ns]; - [task launch]; - -// NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; -// NSURL *url = [NSURL fileURLWithPath:[workspace fullPathForApplication:app_name_ns]]; -// -// NSError *error = nil; -// [workspace launchApplicationAtURL:url options:0 configuration:[NSDictionary dictionaryWithObject:args_ns forKey:NSWorkspaceLaunchConfigurationArguments] error:&error]; - //TODO Handle error - - [pool release]; - return; -} - void force_ns_sxeption() { NSException *exception = [NSException exceptionWithName:@"Forced NSException" reason:nullptr userInfo:nullptr]; diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index aab6d005739..b074c40c175 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -258,6 +258,11 @@ void infos(const std::string& message) int main( int argc, char **argv ) { + // Call Tracy first thing to have it allocate memory + // https://github.com/wolfpld/tracy/issues/196 + LL_PROFILER_FRAME_END; + LL_PROFILER_SET_THREAD_NAME("App"); + // Store off the command line args for use later. gArgC = argc; gArgV = argv; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 8477bd30441..a9513381384 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -172,6 +172,15 @@ namespace << '/' << loc.mV[1] << '/' << loc.mV[2]))); } + + LLAppViewer* app = LLAppViewer::instance(); + if (!app->isSecondInstance() && !app->errorMarkerExists()) + { + // If marker doesn't exist, create a marker with 'other' code for next launch + // otherwise don't override existing file + // Any unmarked crashes will be considered as freezes + app->createErrorMarker(LAST_EXEC_OTHER_CRASH); + } } // MDSCB_EXCEPTIONCODE return false; @@ -253,8 +262,8 @@ void ll_nvapi_init(NvDRSSessionHandle hSession) NvAPI_UnicodeString profile_name; std::string app_name = LLTrans::getString("APP_NAME"); - llutf16string w_app_name = utf8str_to_utf16str(app_name); - wsprintf(profile_name, L"%s", w_app_name.c_str()); + std::wstring w_app_name = ll_convert(app_name); + wsprintf(reinterpret_cast(profile_name), L"%s", w_app_name.c_str()); NvDRSProfileHandle hProfile = 0; // (3) Check if we already have an application profile for the viewer status = NvAPI_DRS_FindProfileByName(hSession, profile_name, &hProfile); @@ -271,7 +280,7 @@ void ll_nvapi_init(NvDRSSessionHandle hSession) NVDRS_PROFILE profileInfo; profileInfo.version = NVDRS_PROFILE_VER; profileInfo.isPredefined = 0; - wsprintf(profileInfo.profileName, L"%s", w_app_name.c_str()); + wsprintf(reinterpret_cast(profileInfo.profileName), L"%s", w_app_name.c_str()); status = NvAPI_DRS_CreateProfile(hSession, &profileInfo, &hProfile); if (status != NVAPI_OK) @@ -286,9 +295,9 @@ void ll_nvapi_init(NvDRSSessionHandle hSession) NVDRS_APPLICATION profile_application; profile_application.version = NVDRS_APPLICATION_VER; - llutf16string w_exe_name = utf8str_to_utf16str(exe_name); + std::wstring w_exe_name = ll_convert(exe_name); NvAPI_UnicodeString profile_app_name; - wsprintf(profile_app_name, L"%s", w_exe_name.c_str()); + wsprintf(reinterpret_cast(profile_app_name), L"%s", w_exe_name.c_str()); status = NvAPI_DRS_GetApplicationInfo(hSession, hProfile, profile_app_name, &profile_application); if (status != NVAPI_OK && status != NVAPI_EXECUTABLE_NOT_FOUND) @@ -304,10 +313,10 @@ void ll_nvapi_init(NvDRSSessionHandle hSession) NVDRS_APPLICATION application; application.version = NVDRS_APPLICATION_VER; application.isPredefined = 0; - wsprintf(application.appName, L"%s", w_exe_name.c_str()); - wsprintf(application.userFriendlyName, L"%s", w_exe_name.c_str()); - wsprintf(application.launcher, L"%s", w_exe_name.c_str()); - wsprintf(application.fileInFolder, L"%s", ""); + wsprintf(reinterpret_cast(application.appName), L"%s", w_exe_name.c_str()); + wsprintf(reinterpret_cast(application.userFriendlyName), L"%s", w_exe_name.c_str()); + wsprintf(reinterpret_cast(application.launcher), L"%s", w_exe_name.c_str()); + wsprintf(reinterpret_cast(application.fileInFolder), L"%s", ""); status = NvAPI_DRS_CreateApplication(hSession, hProfile, &application); if (status != NVAPI_OK) @@ -581,7 +590,7 @@ void LLAppViewerWin32::disableWinErrorReporting() { std::string executable_name = gDirUtilp->getExecutableFilename(); - if( S_OK == WerAddExcludedApplication( utf8str_to_utf16str(executable_name).c_str(), FALSE ) ) + if( S_OK == WerAddExcludedApplication(ll_convert(executable_name).c_str(), FALSE ) ) { LL_INFOS() << "WerAddExcludedApplication() succeeded for " << executable_name << LL_ENDL; } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index a966253c2c8..c1af09ebc76 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -189,7 +189,14 @@ class LLChatHistoryHeader: public LLPanel std::string url = "secondlife://" + mObjectData["slurl"].asString(); LLUrlAction::teleportToLocation(url); } - + else if (level == "obj_zoom_in") + { + LLUUID obj_id = mObjectData["object_id"]; + if (obj_id.notNull()) + { + handle_zoom_to_object(obj_id); + } + } } bool onObjectIconContextMenuItemVisible(const LLSD& userdata) @@ -203,6 +210,16 @@ class LLChatHistoryHeader: public LLPanel { return !LLMuteList::getInstance()->isMuted(getAvatarId(), mFrom, LLMute::flagTextChat); } + else if (level == "obj_zoom_in") + { + LLUUID obj_id = mObjectData["object_id"]; + if (obj_id.notNull()) + { + LLViewerObject* object = gObjectList.findObject(obj_id); + return object && object->isReachable(); + } + return false; + } return false; } @@ -425,6 +442,7 @@ class LLChatHistoryHeader: public LLPanel time_t current_time = time_corrected(); time_t message_time = (time_t)(current_time - LLFrameTimer::getElapsedSeconds() + mTime); + // Report abuse shouldn't use AM/PM, use 24-hour time time_string = "[" + LLTrans::getString("TimeMonth") + "]/[" + LLTrans::getString("TimeDay") + "]/[" + LLTrans::getString("TimeYear") + "] [" @@ -1101,7 +1119,11 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p) mEditor = LLUICtrlFactory::create(editor_params, this); mEditor->setIsFriendCallback(LLAvatarActions::isFriend); mEditor->setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0)); - + mEditor->setIsObjectReachableCallback([](const LLUUID& obj_id) + { + LLViewerObject* object = gObjectList.findObject(obj_id); + return object && object->isReachable(); + }); } LLSD LLChatHistory::getValue() const diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 550dfeb802b..5ac4ce0d522 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -37,6 +37,8 @@ #include "lllocalcliprect.h" #include "lltrans.h" #include "llfloaterimnearbychat.h" +#include "llfloaterworldmap.h" +#include "llviewermenu.h" #include "llviewercontrol.h" #include "llagentdata.h" @@ -75,6 +77,23 @@ class LLObjectHandler : public LLCommandHandler return true; } + if (verb == "zoomin") + { + if (!handle_zoom_to_object(object_id) && params.size() > 2) + { + // zoom faled, show location + // secondlife:///app/object/object_id/zoomin/{LOCATION}/{COORDS} SLapp + const std::string region_name = LLURI::unescape(params[0].asString()); + S32 x = (params.size() > 1) ? params[1].asInteger() : 128; + S32 y = (params.size() > 2) ? params[2].asInteger() : 128; + S32 z = (params.size() > 3) ? params[3].asInteger() : 0; + + LLFloaterWorldMap::getInstance()->trackURL(region_name, x, y, z); + LLFloaterReg::showInstance("world_map", "center"); + } + return true; + } + return false; } }; diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 552ea75559a..32d0f3fa1b4 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -122,9 +122,9 @@ namespace class LLQueuedScriptAssetUpload : public LLScriptAssetUpload { public: - LLQueuedScriptAssetUpload(LLUUID taskId, LLUUID itemId, LLUUID assetId, TargetType_t targetType, + LLQueuedScriptAssetUpload(LLUUID taskId, LLUUID itemId, LLUUID assetId, std::string compileTarget, bool isRunning, std::string scriptName, LLUUID queueId, LLUUID exerienceId, taskUploadFinish_f finish) : - LLScriptAssetUpload(taskId, itemId, targetType, isRunning, + LLScriptAssetUpload(taskId, itemId, compileTarget, isRunning, exerienceId, std::string(), finish, nullptr), mScriptName(scriptName), mQueueId(queueId) @@ -183,9 +183,7 @@ struct LLScriptQueueData // Default constructor LLFloaterScriptQueue::LLFloaterScriptQueue(const LLSD& key) : - LLFloater(key), - mDone(false), - mMono(false) + LLFloater(key) { } @@ -197,7 +195,7 @@ LLFloaterScriptQueue::~LLFloaterScriptQueue() bool LLFloaterScriptQueue::postBuild() { - childSetAction("close",onCloseBtn,this); + childSetAction("close", onCloseBtn, this); getChildView("close")->setEnabled(false); setVisible(true); return true; @@ -222,8 +220,8 @@ bool LLFloaterScriptQueue::start() LLStringUtil::format_map_t args; args["[START]"] = mStartString; - args["[COUNT]"] = llformat ("%d", mObjectList.size()); - buffer = getString ("Starting", args); + args["[COUNT]"] = llformat("%d", mObjectList.size()); + buffer = getString("Starting", args); getChild("queue output")->addSimpleElement(buffer, ADD_BOTTOM); @@ -276,8 +274,8 @@ bool LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const return mExperienceIds.find(id) != mExperienceIds.end(); } -// //Attempt to record this asset ID. If it can not be inserted into the set -// //then it has already been processed so return false. +// Attempt to record this asset ID. If it can not be inserted into the set +// then it has already been processed so return false. void LLFloaterCompileQueue::handleHTTPResponse(std::string pumpName, const LLSD &expresult) { @@ -359,7 +357,7 @@ bool LLFloaterCompileQueue::processScript(LLHandle hfloat LLCheckedHandle floater(hfloater); // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. // which is caught in objectScriptProcessingQueueCoro - bool monocompile = floater->mMono; + std::string compile_target = floater->mCompileTarget; // Initial test to see if we can (or should) attempt to compile the script. LLInventoryItem *item = dynamic_cast(inventory); @@ -470,7 +468,7 @@ bool LLFloaterCompileQueue::processScript(LLHandle hfloat LLResourceUploadInfo::ptr_t uploadInfo(new LLQueuedScriptAssetUpload(object->getID(), inventory->getUUID(), assetId, - monocompile ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2, + compile_target, true, inventory->getName(), LLUUID(), diff --git a/indra/newview/llcompilequeue.h b/indra/newview/llcompilequeue.h index 951d4800e8c..42af5b18812 100644 --- a/indra/newview/llcompilequeue.h +++ b/indra/newview/llcompilequeue.h @@ -55,7 +55,7 @@ class LLFloaterScriptQueue : public LLFloater/*, public LLVOInventoryListener*/ /*virtual*/ bool postBuild(); - void setMono(bool mono) { mMono = mono; } + void setCompileTarget(std::string target) { mCompileTarget = target; } // addObject() accepts an object id. void addObject(const LLUUID& id, std::string name); @@ -80,8 +80,8 @@ class LLFloaterScriptQueue : public LLFloater/*, public LLVOInventoryListener*/ protected: // UI - LLScrollListCtrl* mMessages; - LLButton* mCloseBtn; + LLScrollListCtrl* mMessages { nullptr }; + LLButton* mCloseBtn { nullptr }; // Object Queue struct ObjectData @@ -93,14 +93,13 @@ class LLFloaterScriptQueue : public LLFloater/*, public LLVOInventoryListener*/ object_data_list_t mObjectList; LLUUID mCurrentObjectID; - bool mDone; + bool mDone { false }; std::string mStartString; - bool mMono; + std::string mCompileTarget { "lsl2" }; typedef boost::function &, LLInventoryObject*, LLEventPump &)> fnQueueAction_t; static void objectScriptProcessingQueueCoro(std::string action, LLHandle hfloater, object_data_list_t objectList, fnQueueAction_t func); - }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index cea68c1779a..65a068e08d3 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -118,11 +118,21 @@ const std::string LLConversation::createTimestamp(const U64Seconds& utc_time) LLSD substitution; substitution["datetime"] = (S32)utc_time.value(); - timeStr = "["+LLTrans::getString ("TimeMonth")+"]/[" - +LLTrans::getString ("TimeDay")+"]/[" - +LLTrans::getString ("TimeYear")+"] [" - +LLTrans::getString ("TimeHour")+"]:[" - +LLTrans::getString ("TimeMin")+"]"; + static bool use_24h = gSavedSettings.getBOOL("Use24HourClock"); + timeStr = "[" + LLTrans::getString("TimeMonth") + "]/[" + + LLTrans::getString("TimeDay") + "]/[" + + LLTrans::getString("TimeYear") + "] ["; + if (use_24h) + { + timeStr += LLTrans::getString("TimeHour") + "]:[" + + LLTrans::getString("TimeMin") + "]"; + } + else + { + timeStr += LLTrans::getString("TimeHour12") + "]:[" + + LLTrans::getString("TimeMin") + "] [" + + LLTrans::getString("TimeAMPM") + "]"; + } LLStringUtil::format (timeStr, substitution); diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 0e0ab236d65..99d770b6e27 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -543,7 +543,7 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi { bool old_value = mIsInActiveVoiceChannel; mIsInActiveVoiceChannel = vmi->getUUID() == session_id; - mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel); + mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel && !LLVoiceChannel::isSuspended()); if (old_value != mIsInActiveVoiceChannel) { refresh(); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 1c8864a9df3..46696fc4a4c 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -204,7 +204,7 @@ class LLRenderPass : public LLDrawPool NUM_RENDER_TYPES, }; - #ifdef LL_PROFILER_ENABLE_RENDER_DOC + #if LL_PROFILER_ENABLE_RENDER_DOC static inline const char* lookupPassName(U32 pass) { switch (pass) @@ -340,7 +340,7 @@ class LLRenderPass : public LLDrawPool } } #else - static inline const char* lookupPass(U32 pass) { return ""; } + static inline const char* lookupPassName(U32 pass) { return ""; } #endif LLRenderPass(const U32 type); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 7d58511d41e..cdf3244389b 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -143,7 +143,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass) gGL.setColorMask(true, true); LLColor3 light_diffuse(0, 0, 0); - F32 light_exp = 0.0f; LLEnvironment& environment = LLEnvironment::instance(); LLSettingsWater::ptr_t pwater = environment.getCurrentWater(); @@ -170,7 +169,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass) // Apply magic numbers translating light direction into intensities light_dir.normalize(); F32 ground_proj_sq = light_dir.mV[0] * light_dir.mV[0] + light_dir.mV[1] * light_dir.mV[1]; - light_exp = llmax(32.f, 256.f * powf(ground_proj_sq, 16.0f)); if (0.f < light_diffuse.normalize()) // Normalizing a color? Puzzling... { light_diffuse *= (1.5f + (6.f * ground_proj_sq)); diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index c6fea1ba825..86c58a3497b 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -54,13 +54,6 @@ namespace Details void stop(); private: - // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error. - // This means we attempt to recover relatively quickly but back off giving more time to recover - // until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts. - static const F32 EVENT_POLL_ERROR_RETRY_SECONDS; - static const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC; - static const S32 MAX_EVENT_POLL_HTTP_ERRORS; - void eventPollCoro(std::string url); void handleMessage(const LLSD &content); @@ -76,9 +69,13 @@ namespace Details }; - const F32 LLEventPollImpl::EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout. - const F32 LLEventPollImpl::EVENT_POLL_ERROR_RETRY_SECONDS_INC = 5.f; // ~ half of a normal timeout. - const S32 LLEventPollImpl::MAX_EVENT_POLL_HTTP_ERRORS = 10; // ~5 minutes, by the above rules. + // We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error. + // This means we attempt to recover relatively quickly but back off giving more time to recover + // until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts. + constexpr F32 EVENT_POLL_ERROR_RETRY_SECONDS = 15.f; // ~ half of a normal timeout. + constexpr F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC = 5.f; // ~ half of a normal timeout. + constexpr S32 MAX_EVENT_POLL_HTTP_ERRORS = 10; // ~5 minutes, by the above rules. + constexpr F64 MIN_SECONDS_PASSED = 10.0; // Minimum time we expect the server to hold the request. int LLEventPollImpl::sNextCounter = 1; @@ -151,11 +148,17 @@ namespace Details LLSD acknowledge; int errorCount = 0; int counter = mCounter; // saved on the stack for logging. + LLTimer message_time; LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL; mAdapter = httpAdapter; + // This is a loop with its own waitToRetry implementation, + // so disable retries. + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setRetries(0); + LL::WorkQueue::ptr_t main_queue = nullptr; // HACK -- grab the mainloop workqueue to move execution of the handler @@ -172,11 +175,13 @@ namespace Details request["ack"] = acknowledge; request["done"] = mDone; + message_time.reset(); + // LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> request = " // << LLSDXMLStreamer(request) << LL_ENDL; LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> posting and yielding." << LL_ENDL; - LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request); + LLSD result = httpAdapter->postAndSuspend(mHttpRequest, url, request, httpOpts); // LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = " // << LLSDXMLStreamer(result) << LL_ENDL; @@ -194,11 +199,30 @@ namespace Details if (!status) { - if (status == LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT)) - { // A standard timeout response we get this when there are no events. - LL_DEBUGS("LLEventPollImpl") << "All is very quiet on target server. It may have gone idle?" << LL_ENDL; - errorCount = 0; - continue; + if (status == LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT) // A standard timeout, no events. + || status == LLCore::HttpStatus(HTTP_BAD_GATEWAY) // An expected 'No events' case. + || status == LLCore::HttpStatus(HTTP_INTERNAL_ERROR) + || status == LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE) + || status == LLCore::HttpStatus(HTTP_GATEWAY_TIME_OUT)) + { + if (message_time.getElapsedSeconds() < MIN_SECONDS_PASSED) + { + // Server is supposed to hold request for 20 to 30 seconds. + // If it didn't hold the request at least for 10s, treat as an error. + LL_WARNS("LLEventPollImpl") << "Response arrived too early, status: " << status.toTerseString() + << ", time passed: " << message_time.getElapsedSeconds() << LL_ENDL; + } + else + { + // Timeout, expected and means 'no events'. Request is to be re-issued immediately. + // Current definition of a timeout is any of : + // - libcurl easy 28 status code + // - Linden 499 special http status code + // - RFC - standard 502 - 504 http status codes + LL_DEBUGS("LLEventPollImpl") << "No events, from: " << mSenderIp <<" status: " << (S32)status.getStatus() << LL_ENDL; + errorCount = 0; + continue; + } } else if ((status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_OP_CANCELED)) || (status == LLCore::HttpStatus(HTTP_NOT_FOUND))) @@ -206,13 +230,13 @@ namespace Details // some cases the server gets ahead of the viewer and will // return a 404 error (Not Found) before the cancel event // comes back in the queue - LL_WARNS("LLEventPollImpl") << "Canceling coroutine" << LL_ENDL; + LL_WARNS("LLEventPollImpl") << "<" << counter << "> Canceling coroutine, status: " << status.toTerseString() << LL_ENDL; break; } else if (!status.isHttpStatus()) { /// Some LLCore or LIBCurl error was returned. This is unlikely to be recoverable - LL_WARNS("LLEventPollImpl") << "Critical error from poll request returned from libraries. Canceling coroutine." << LL_ENDL; + LL_WARNS("LLEventPollImpl") << "<" << counter << "> Critical error from poll request returned from libraries. Canceling coroutine." << LL_ENDL; break; } LL_WARNS("LLEventPollImpl") << "<" << counter << "> Error result from LLCoreHttpUtil::HttpCoroHandler. Code " @@ -255,6 +279,10 @@ namespace Details LL_WARNS("LLEventPollImpl") << "< " << counter << "> Forcing disconnect due to stalled main region event poll." << LL_ENDL; LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection")); } + else + { + LL_WARNS("LLEventPollImpl") << "< " << counter << "> Stopping event poll for " << mSenderIp << " due to failures." << LL_ENDL; + } break; } } diff --git a/indra/newview/lleventpoll.h b/indra/newview/lleventpoll.h index bb407b3799c..ea186aa803a 100644 --- a/indra/newview/lleventpoll.h +++ b/indra/newview/lleventpoll.h @@ -40,7 +40,30 @@ namespace Details class LLEventPoll - ///< implements the viewer side of server-to-viewer pushed events. + ///< Implements the viewer side of server-to-viewer pushed events. + /// + /// This class implements the sole consumer of the EventQueueGet capability + /// and delivers data, including llsd-encoded llmessage payloads, from + /// simulator to viewer. + /// + /// https://wiki.secondlife.com/wiki/EventQueueGet + /// The wiki page is neither complete nor entirely correct. Request timeouts + /// became the de facto method of returning an empty event set to the viewer. + /// But the timeout behavior was never defined. It was simply whatever + /// behavior a given grid implementation implemented. + /// + /// In SL's case, the path may include reverse proxies, http caches, http and + /// socks proxies, transparent hijacking, and other horrors. A pitfall for + /// implementors. + /// + /// Current definition of a timeout is any of : + /// - libcurl easy 28 status code + /// - Linden 499 special http status code + /// - RFC - standard 502 - 504 http status codes + /// If requests are failing too quickly with the above errors, they are treated + /// as actual errors and not an empty payload. These will count towards a final + /// error declaration and can lead to disconnection from a simulator or the + /// entire grid. { public: LLEventPoll(const std::string& pollURL, const LLHost& sender); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 373a556f864..f08ef8d24a8 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -767,9 +767,6 @@ static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVect // Texture transforms are done about the center of the face. st.setAdd(tex_coord, trans); - // Handle rotation - LLVector4a rot_st; - // LLVector4a s0; s0.splat(st, 0); @@ -842,7 +839,6 @@ bool LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, //VECTORIZE THIS LLMatrix4a mat_vert; mat_vert.loadu(mat_vert_in); - LLVector4a new_extents[2]; llassert(less_than_max_mag(face.mExtents[0])); llassert(less_than_max_mag(face.mExtents[1])); @@ -2255,8 +2251,6 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) if (joint) { - LLVector4a jointPos; - LLMatrix4a worldMat; worldMat.loadu((F32*)&joint->getWorldMatrix().mMatrix[0][0]); diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 558fc920180..a05f7256730 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -222,6 +222,14 @@ void LLFetchedGLTFMaterial::updateTextureTracking() } } +void LLFetchedGLTFMaterial::clearFetchedTextures() +{ + mBaseColorTexture = nullptr; + mNormalTexture = nullptr; + mMetallicRoughnessTexture = nullptr; + mEmissiveTexture = nullptr; +} + void LLFetchedGLTFMaterial::materialBegin() { llassert(!mFetching); diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 4a33b9f05f5..074e3fef415 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -67,6 +67,7 @@ class LLFetchedGLTFMaterial: public LLGLTFMaterial LLPointer mNormalTexture; LLPointer mMetallicRoughnessTexture; LLPointer mEmissiveTexture; + void clearFetchedTextures(); std::set mTextureEntires; diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 41e954b7fab..0e754c95612 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -287,7 +287,7 @@ bool LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) success = GetOpenFileName(&mOFN); if (success) { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); + std::string filename = ll_convert(std::wstring(mFilesW)); mFiles.push_back(filename); } @@ -353,7 +353,7 @@ bool LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking) // lengths. if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/ { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); + std::string filename = ll_convert(std::wstring(mFilesW)); mFiles.push_back(filename); } else @@ -367,7 +367,7 @@ bool LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking) break; if (*tptrw == 0) tptrw++; // shouldn't happen? - std::string filename = utf16str_to_utf8str(llutf16string(tptrw)); + std::string filename = ll_convert(std::wstring(tptrw)); if (dirname.empty()) dirname = filename + "\\"; else @@ -413,7 +413,7 @@ bool LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, mOFN.lpstrFile = mFilesW; if (!filename.empty()) { - llutf16string tstring = utf8str_to_utf16str(filename); + std::wstring tstring = ll_convert(filename); wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ else { @@ -595,7 +595,7 @@ bool LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, success = GetSaveFileName(&mOFN); if (success) { - std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); + std::string filename = ll_convert(std::wstring(mFilesW)); mFiles.push_back(filename); } } diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm index b21bc724fbb..978069457ce 100644 --- a/indra/newview/llfilepicker_mac.mm +++ b/indra/newview/llfilepicker_mac.mm @@ -86,7 +86,7 @@ result = [panel runModal]; - if (result == NSOKButton) + if (result == NSModalResponseOK) { NSArray *filesToOpen = [panel URLs]; int i, count = [filesToOpen count]; @@ -173,7 +173,7 @@ void doLoadDialogModeless(const std::vector* allowed_types, [panel setNameFieldStringValue: fileName]; [panel setDirectoryURL: url]; if([panel runModal] == - NSFileHandlingPanelOKButton) + NSModalResponseOK) { NSURL* url = [panel URL]; NSString* p = [url path]; @@ -211,7 +211,7 @@ void doSaveDialogModeless(const std::string* file, [panel beginWithCompletionHandler:^(NSModalResponse result) { - if (result == NSOKButton) + if (result == NSModalResponseOK) { NSURL* url = [panel URL]; NSString* p = [url path]; diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp index 236aadfbc1b..4843a48e66b 100644 --- a/indra/newview/llfloaterdisplayname.cpp +++ b/indra/newview/llfloaterdisplayname.cpp @@ -56,6 +56,7 @@ class LLFloaterDisplayName : public LLFloater void onCacheSetName(bool success, const std::string& reason, const LLSD& content); + bool mIsLockedOut = false; }; LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) : @@ -72,8 +73,8 @@ void LLFloaterDisplayName::onOpen(const LLSD& key) LLAvatarNameCache::get(gAgent.getID(), &av_name); F64 now_secs = LLDate::now().secondsSinceEpoch(); - - if (now_secs < av_name.mNextUpdate) + mIsLockedOut = now_secs < av_name.mNextUpdate; + if (mIsLockedOut) { // ...can't update until some time in the future F64 next_update_local_secs = @@ -167,18 +168,19 @@ void LLFloaterDisplayName::onReset() } getChild("display_name_editor")->setValue(av_name.getUserName()); - if (getChild("display_name_editor")->getEnabled()) + if (mIsLockedOut) { - // UI is enabled, fill the first field - getChild("display_name_confirm")->clear(); - getChild("display_name_confirm")->setFocus(true); + // UI is disabled. + // We should allow resetting even if user already + // set a display name, enable save button + getChild("display_name_confirm")->setValue(av_name.getUserName()); + getChild("save_btn")->setEnabled(true); } else { - // UI is disabled, looks like we should allow resetting - // even if user already set a display name, enable save button - getChild("display_name_confirm")->setValue(av_name.getUserName()); - getChild("save_btn")->setEnabled(true); + // UI is enabled, focus on the confirm field + getChild("display_name_confirm")->clear(); + getChild("display_name_confirm")->setFocus(true); } } diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp index 7e135031031..c5f4a2f0cf4 100644 --- a/indra/newview/llfloateremojipicker.cpp +++ b/indra/newview/llfloateremojipicker.cpp @@ -1284,7 +1284,7 @@ void LLFloaterEmojiPicker::saveState() if (!recentlyUsed.empty()) recentlyUsed += ","; char buffer[32]; - sprintf(buffer, "%u", (U32)emoji); + snprintf(buffer, sizeof(buffer), "%u", (U32)emoji); recentlyUsed += buffer; if (!--maxCount) break; @@ -1301,7 +1301,7 @@ void LLFloaterEmojiPicker::saveState() if (!frequentlyUsed.empty()) frequentlyUsed += ","; char buffer[32]; - sprintf(buffer, "%u:%u", (U32)it.first, (U32)it.second); + snprintf(buffer, sizeof(buffer), "%u:%u", (U32)it.first, (U32)it.second); frequentlyUsed += buffer; if (!--maxCount) break; diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index d28c987414c..1825797159e 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -134,12 +134,15 @@ void LLFloaterFixedEnvironment::onClose(bool app_quitting) { doCloseInventoryFloater(app_quitting); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().setCurrentEnvironmentSelection(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT); + if (!app_quitting) + { + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + LLEnvironment::instance().setCurrentEnvironmentSelection(LLEnvironment::ENV_LOCAL); + LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT); - mSettings.reset(); - syncronizeTabs(); + mSettings.reset(); + syncronizeTabs(); + } } void LLFloaterFixedEnvironment::refresh() diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index c920a3c8989..3b0c19499a0 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -44,6 +44,7 @@ #include "llfloaterimcontainer.h" #include "llrootview.h" #include "lllayoutstack.h" +#include "llscripteditorws.h" //add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace using namespace LLNotificationsUI; @@ -335,6 +336,7 @@ void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat) { if (!gSavedSettings.getBOOL("ShowScriptErrors")) return; + if (gSavedSettings.getS32("ShowScriptErrorsLocation") == 1) return; } @@ -526,6 +528,15 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, if (!gSavedSettings.getBOOL("ShowScriptErrors")) return; + if (gSavedSettings.getBOOL("ExternalWebsocketSyncEnable") && gSavedSettings.getBOOL("ExternalWebsocketForwardDebug")) + { + LLScriptEditorWSServer::ptr_t server = LLScriptEditorWSServer::getServer(); + if (server) + { + server->forwardChatToIDE(chat_msg); + } + } + // don't process debug messages from not owned objects, see EXT-7762 if (gAgentID != chat_msg.mOwnerID) { @@ -545,6 +556,16 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg, return; } } + else if ((chat_msg.mChatType == CHAT_TYPE_OWNER) && + gSavedSettings.getBOOL("ExternalWebsocketSyncEnable") && + gSavedSettings.getBOOL("ExternalWebsocketForwardDebug")) + { + LLScriptEditorWSServer::ptr_t server = LLScriptEditorWSServer::getServer(); + if (server) + { + server->forwardChatToIDE(chat_msg); + } + } nearby_chat->addMessage(chat_msg, true, args); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index e03422780aa..65c13797ac3 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -618,8 +618,19 @@ void LLFloaterIMSessionTab::deleteAllChildren() std::string LLFloaterIMSessionTab::appendTime() { - std::string timeStr = "[" + LLTrans::getString("TimeHour") + "]:" - "[" + LLTrans::getString("TimeMin") + "]"; + std::string timeStr; + static bool use_24h = gSavedSettings.getBOOL("Use24HourClock"); + if (use_24h) + { + timeStr = "[" + LLTrans::getString("TimeHour") + "]:" + "[" + LLTrans::getString("TimeMin") + "]"; + } + else + { + timeStr = "[" + LLTrans::getString("TimeHour12") + "]:" + "[" + LLTrans::getString("TimeMin") + "] [" + + LLTrans::getString("TimeAMPM") + "]"; + } LLSD substitution; substitution["datetime"] = (S32)time_corrected(); diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 4f993ca0e11..c0fe7ad8962 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -220,7 +220,8 @@ void LLFloaterInspect::refresh() } time_t timestamp = (time_t) (obj->mCreationDate/1000000); - std::string timeStr = getString("timeStamp"); + static bool use_24h = gSavedSettings.getBOOL("Use24HourClock"); + std::string timeStr = use_24h ? getString("timeStamp") : getString("timeStampAMPM"); LLSD substitution; substitution["datetime"] = (S32) timestamp; LLStringUtil::format (timeStr, substitution); diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index 68b11ec92bb..871f924316c 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -78,7 +78,7 @@ BOOL CALLBACK di8_list_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, // Capable of detecting devices like Oculus Rift if (device_instance_ptr && pvRef) { - std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName)); + std::string product_name = ll_convert(std::wstring(device_instance_ptr->tszProductName)); S32 size = sizeof(GUID); LLSD::Binary data; //just an std::vector data.resize(size); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 52a3e78d041..5c5219bcdd9 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -733,7 +733,8 @@ void LLPanelLandGeneral::refresh() // Display claim date time_t claim_date = parcel->getClaimDate(); - std::string claim_date_str = getString("time_stamp_template"); + static bool use_24h = gSavedSettings.getBOOL("Use24HourClock"); + std::string claim_date_str = use_24h ? getString("time_stamp_template") : getString("time_stamp_template_ampm"); LLSD substitution; substitution["datetime"] = (S32) claim_date; LLStringUtil::format (claim_date_str, substitution); diff --git a/indra/newview/llfloatermarketplace.cpp b/indra/newview/llfloatermarketplace.cpp new file mode 100644 index 00000000000..889daf84ab3 --- /dev/null +++ b/indra/newview/llfloatermarketplace.cpp @@ -0,0 +1,47 @@ +/** + * @file llfloatermarketplace.cpp + * @brief floater for the Marketplace web site + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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 "llviewerprecompiledheaders.h" + +#include "llfloatermarketplace.h" +#include "lluictrlfactory.h" + +LLFloaterMarketplace::LLFloaterMarketplace(const LLSD& key) + : LLFloater(key) +{ +} + +LLFloaterMarketplace::~LLFloaterMarketplace() +{ +} + +bool LLFloaterMarketplace::postBuild() +{ + enableResizeCtrls(true, true, false); + return true; +} + + diff --git a/indra/newview/llfloatermarketplace.h b/indra/newview/llfloatermarketplace.h new file mode 100644 index 00000000000..2ae4d0d64a2 --- /dev/null +++ b/indra/newview/llfloatermarketplace.h @@ -0,0 +1,40 @@ +/** + * @file llfloatermarketplace.h + * @brief floater for the Marketplace web site + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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$ + */ + +#pragma once + +#include "llfloater.h" + +class LLFloaterMarketplace: + public LLFloater +{ + friend class LLFloaterReg; +private: + LLFloaterMarketplace(const LLSD& key); + ~LLFloaterMarketplace(); + bool postBuild() override; +}; + diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 9fb9c6346e8..1da99905502 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -346,6 +346,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this)); mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this)); mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this)); + mCommitCallbackRegistrar.add("Pref.Scripting", boost::bind(&LLFloaterPreference::onClickScriptingPerfs, this)); sSkin = gSavedSettings.getString("SkinCurrent"); @@ -367,7 +368,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this)); mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // Hook up for filtering #ifdef LL_DISCORD - gSavedSettings.getControl("EnableDiscord")->getCommitSignal()->connect(boost::bind(&LLAppViewer::toggleDiscordIntegration, _2)); + gSavedSettings.getControl("EnableDiscord")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity)); gSavedSettings.getControl("ShowDiscordActivityDetails")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity)); gSavedSettings.getControl("ShowDiscordActivityState")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity)); #endif @@ -475,6 +476,8 @@ bool LLFloaterPreference::postBuild() getChild("log_path_string")->setEnabled(false); // make it read-only but selectable getChild("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this)); + mTimeFormatCombobox = getChild("time_format_combobox"); + mTimeFormatCombobox->setCommitCallback(boost::bind(&LLFloaterPreference::onTimeFormatChange, this)); getChild("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions")); getChild("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions")); @@ -758,6 +761,7 @@ void LLFloaterPreference::onOpen(const LLSD& key) // Forget previous language changes. mLanguageChanged = false; + mLastQualityLevel = gSavedSettings.getU32("RenderQualityPerformance"); // Display selected maturity icons. onChangeMaturity(); @@ -1102,6 +1106,13 @@ void LLFloaterPreference::onLanguageChange() } } +void LLFloaterPreference::onTimeFormatChange() +{ + std::string val = mTimeFormatCombobox->getValue(); + gSavedSettings.setBOOL("Use24HourClock", val == "1"); + onLanguageChange(); +} + void LLFloaterPreference::onNotificationsChange(const std::string& OptionName) { mNotificationOptions[OptionName] = getChild(OptionName)->getSelectedItemLabel(); @@ -1317,6 +1328,8 @@ void LLFloaterPreference::refresh() advanced->refresh(); } updateClickActionViews(); + + mTimeFormatCombobox->selectByValue(gSavedSettings.getBOOL("Use24HourClock") ? "1" : "0"); } void LLFloaterPreference::onCommitWindowedMode() @@ -1327,7 +1340,35 @@ void LLFloaterPreference::onCommitWindowedMode() void LLFloaterPreference::onChangeQuality(const LLSD& data) { U32 level = (U32)(data.asReal()); + constexpr U32 LVL_HIGH = 4; + if (level >= LVL_HIGH && mLastQualityLevel < level) + { + constexpr U32 LOW_MEM_THRESHOLD = 4097; + U32 total_mem = (U32Megabytes)LLMemory::getMaxMemKB(); + if (total_mem < LOW_MEM_THRESHOLD) + { + LLSD args; + args["TOTAL_MEM"] = LLSD::Integer(total_mem); + LLNotificationsUtil::add("PreferenceQualityWithLowMemory", args, LLSD(), [this](const LLSD& notification, const LLSD& response) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + // If cancel pressed + if (option == 1) + { + constexpr U32 LVL_MED_PLUS = 3; + gSavedSettings.setU32("RenderQualityPerformance", LVL_MED_PLUS); + mLastQualityLevel = LVL_MED_PLUS; + LLFeatureManager::getInstance()->setGraphicsLevel(LVL_MED_PLUS, true); + refreshEnabledGraphics(); + refresh(); + } + } + ); + } + } + mLastQualityLevel = level; LLFeatureManager::getInstance()->setGraphicsLevel(level, true); + gSavedSettings.setU32("DebugQualityPerformance", level); refreshEnabledGraphics(); refresh(); } @@ -1797,6 +1838,11 @@ void LLFloaterPreference::onClickAdvanced() } } +void LLFloaterPreference::onClickScriptingPerfs() +{ + LLFloaterReg::showInstance("scripting_settings"); +} + void LLFloaterPreference::onClickActionChange() { updateClickActionControls(); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index fa9c421a8f0..831a650c45f 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -117,6 +117,7 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, void onClickClearCache(); // Clear viewer texture cache, file cache on next startup void onClickBrowserClearCache(); // Clear web history and caches as well as viewer caches above void onLanguageChange(); + void onTimeFormatChange(); void onNotificationsChange(const std::string& OptionName); void onNameTagOpacityChange(const LLSD& newvalue); @@ -190,6 +191,7 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, void onClickRenderExceptions(); void onClickAutoAdjustments(); void onClickAdvanced(); + void onClickScriptingPerfs(); void applyUIColor(LLUICtrl* ctrl, const LLSD& param); void getUIColor(LLUICtrl* ctrl, const LLSD& param); void onLogChatHistorySaved(); @@ -218,6 +220,7 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, bool mGotPersonalInfo; bool mLanguageChanged; bool mAvatarDataInitialized; + U32 mLastQualityLevel = 0; std::string mPriorInstantMessageLogPath; bool mOriginalHideOnlineStatus; @@ -234,10 +237,11 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, LLButton* mDeleteTranscriptsBtn = nullptr; LLButton* mEnablePopupBtn = nullptr; LLButton* mDisablePopupBtn = nullptr; + LLComboBox* mTimeFormatCombobox = nullptr; std::unique_ptr< ll::prefs::SearchData > mSearchData; bool mSearchDataDirty; - boost::signals2::connection mImpostorsChangedSignal; + boost::signals2::connection mImpostorsChangedSignal; boost::signals2::connection mComplexityChangedSignal; void onUpdateFilterTerm( bool force = false ); diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h index a1a54f238df..6f793c13799 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h @@ -61,7 +61,7 @@ class LLFloaterPreferenceGraphicsAdvanced : public LLFloater void onBtnOK(const LLSD& userdata); void onBtnCancel(const LLSD& userdata); - boost::signals2::connection mImpostorsChangedSignal; + boost::signals2::connection mImpostorsChangedSignal; boost::signals2::connection mComplexityChangedSignal; boost::signals2::connection mComplexityModeChangedSignal; boost::signals2::connection mLODFactorChangedSignal; diff --git a/indra/newview/llfloaterscripting.cpp b/indra/newview/llfloaterscripting.cpp new file mode 100644 index 00000000000..0719ced58df --- /dev/null +++ b/indra/newview/llfloaterscripting.cpp @@ -0,0 +1,106 @@ +/** + * @file llfloaterscripting.cpp + * @brief Asset creation permission preferences. + * @author Jonathan Yap + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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 "llviewerprecompiledheaders.h" +#include "llcheckboxctrl.h" +#include "llfloaterscripting.h" +#include "llviewercontrol.h" +#include "llviewerwindow.h" +#include "lluictrlfactory.h" +#include "llpermissions.h" +#include "llagent.h" +#include "llviewerregion.h" +#include "llnotificationsutil.h" +#include "llsdserialize.h" +#include "llvoavatar.h" +#include "llcorehttputil.h" +#include "lleventfilter.h" +#include "lleventcoro.h" +#include "llviewermenufile.h" +#include "llappviewer.h" + +namespace +{ + class LLEditorPicker : public LLFilePickerThread + { + public: + LLEditorPicker(LLFloaterScripting *floater): + LLFilePickerThread(LLFilePicker::FFLOAD_EXE) + { + mHandle = floater->getDerivedHandle(); + } + void notify(const std::vector& filenames) override + { + if (LLAppViewer::instance()->quitRequested()) + { + return; + } + + LLFloaterScripting* floater = mHandle.get(); + if (floater && !filenames.empty()) + { + floater->pickedEditor(filenames.front()); + } + } + + private: + LLHandle mHandle; + }; + +} + +LLFloaterScripting::LLFloaterScripting(const LLSD& seed) + : LLFloater(seed) +{ + mCommitCallbackRegistrar.add("ScriptingSettings.CLOSE", boost::bind(&LLFloaterScripting::onClickClose, this)); + mCommitCallbackRegistrar.add("ScriptingSettings.BROWSE", boost::bind(&LLFloaterScripting::onClickBrowse, this)); +} + +bool LLFloaterScripting::postBuild() +{ + refresh(); + return true; +} + +void LLFloaterScripting::onClickClose() +{ + closeFloater(); +} + +void LLFloaterScripting::onClickBrowse() +{ + (new LLEditorPicker(this))->getFile(); +} + +void LLFloaterScripting::pickedEditor(std::string_view editor) +{ + assert_main_thread(); + std::stringstream cmdline; + cmdline << "\"" << editor << "\" \"%s\""; + + gSavedSettings.setString("ExternalEditor", cmdline.str()); +} diff --git a/indra/newview/llfloaterscripting.h b/indra/newview/llfloaterscripting.h new file mode 100644 index 00000000000..ca7bd3e091a --- /dev/null +++ b/indra/newview/llfloaterscripting.h @@ -0,0 +1,49 @@ +/** + * @file llfloaterscripting.h + * @brief Asset creation permission preferences. + * @author Jonathan Yap + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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$ + */ + +#pragma once + +#include "llfloater.h" +#include "lleventcoro.h" +#include "llcoros.h" + +class LLFloaterScripting : public LLFloater +{ + friend class LLFloaterReg; + +public: + bool postBuild() override; + void onClickClose(); + void onClickBrowse(); + + void pickedEditor(std::string_view editor); + +private: + LLFloaterScripting(const LLSD& seed); + +}; + diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index d3c8bf34513..8e6a47dce5d 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -1,11 +1,10 @@ /** * @file llfloatersearch.cpp - * @author Martin Reddy - * @brief Search floater - uses an embedded web browser control + * @brief Floater for Search (update 2025, preload) * - * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, 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 @@ -27,68 +26,48 @@ #include "llviewerprecompiledheaders.h" +#include "llfloatersearch.h" + +#include "llagent.h" #include "llcommandhandler.h" #include "llfloaterreg.h" -#include "llfloatersearch.h" -#include "llhttpconstants.h" #include "llmediactrl.h" -#include "llnotificationsutil.h" -#include "lllogininstance.h" -#include "lluri.h" -#include "llagent.h" -#include "llui.h" +#include "lluictrlfactory.h" #include "llviewercontrol.h" #include "llweb.h" // support secondlife:///app/search/{CATEGORY}/{QUERY} SLapps -class LLSearchHandler : public LLCommandHandler -{ -public: - // requires trusted browser to trigger - LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_CLICK_ONLY) { } - bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) - { - const size_t parts = tokens.size(); +class LLSearchHandler : public LLCommandHandler { + public: + // requires trusted browser to trigger + LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_CLICK_ONLY) { } + bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) { + const size_t parts = tokens.size(); + + // get the (optional) category for the search + std::string collection; + if (parts > 0) + { + collection = tokens[0].asString(); + } - // get the (optional) category for the search - std::string collection; - if (parts > 0) - { - collection = tokens[0].asString(); - } + // get the (optional) search string + std::string search_text; + if (parts > 1) + { + search_text = tokens[1].asString(); + } - // get the (optional) search string - std::string search_text; - if (parts > 1) - { - search_text = tokens[1].asString(); + // open the search floater and perform the requested search + LLFloaterReg::showInstance("search", llsd::map("collection", collection,"query", search_text)); + return true; } - - // create the LLSD arguments for the search floater - LLFloaterSearch::Params p; - p.search.collection = collection; - p.search.query = LLURI::unescape(search_text); - - // open the search floater and perform the requested search - LLFloaterReg::showInstance("search", p); - return true; - } }; LLSearchHandler gSearchHandler; -LLFloaterSearch::SearchQuery::SearchQuery() -: category("category", ""), - collection("collection", ""), - query("query") -{} - -LLFloaterSearch::LLFloaterSearch(const Params& key) : - LLFloaterWebContent(key), - mSearchGodLevel(0) +LLFloaterSearch::LLFloaterSearch(const LLSD& key) + : LLFloater(key) { - // declare a map that transforms a category name into - // the URL suffix that is used to search that category - mSearchType.insert("standard"); mSearchType.insert("land"); mSearchType.insert("classified"); @@ -100,76 +79,47 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) : mCollectionType.insert("people"); } -bool LLFloaterSearch::postBuild() -{ - LLFloaterWebContent::postBuild(); - mWebBrowser->addObserver(this); - - return true; -} - -void LLFloaterSearch::onOpen(const LLSD& key) +LLFloaterSearch::~LLFloaterSearch() { - Params p(key); - p.trusted_content = true; - p.allow_address_entry = false; - - LLFloaterWebContent::onOpen(p); - mWebBrowser->setFocus(true); - search(p.search); } -void LLFloaterSearch::onClose(bool app_quitting) +void LLFloaterSearch::onOpen(const LLSD& tokens) { - LLFloaterWebContent::onClose(app_quitting); - // tear down the web view so we don't show the previous search - // result when the floater is opened next time - destroy(); + initiateSearch(tokens); } -void LLFloaterSearch::godLevelChanged(U8 godlevel) +void LLFloaterSearch::initiateSearch(const LLSD& tokens) { - // search results can change based upon god level - if the user - // changes god level, then give them a warning (we don't refresh - // the search as this might undo any page navigation or - // AJAX-driven changes since the last search). + std::string url = gSavedSettings.getString("SearchURL"); - //FIXME: set status bar text + LLSD subs; - //getChildView("refresh_search")->setVisible( (godlevel != mSearchGodLevel)); -} + // Setting this substitution here results in a full set of collections being + // substituted into the final URL using the logic from the original search. + subs["TYPE"] = "standard"; -void LLFloaterSearch::search(const SearchQuery &p) -{ - if (! mWebBrowser || !p.validateBlock()) - { - return; - } + std::string collection = tokens.has("collection") ? tokens["collection"].asString() : ""; - // reset the god level warning as we're sending the latest state - getChildView("refresh_search")->setVisible(false); - mSearchGodLevel = gAgent.getGodLevel(); + std::string search_text = tokens.has("query") ? tokens["query"].asString() : ""; - // work out the subdir to use based on the requested category - LLSD subs; - if (mSearchType.find(p.category) != mSearchType.end()) + std::string category = tokens.has("category") ? tokens["category"].asString() : ""; + if (mSearchType.find(category) != mSearchType.end()) { - subs["TYPE"] = p.category; + subs["TYPE"] = category; } else { subs["TYPE"] = "standard"; } - // add the search query string - subs["QUERY"] = LLURI::escape(p.query); + subs["QUERY"] = LLURI::escape(search_text); subs["COLLECTION"] = ""; if (subs["TYPE"] == "standard") { - if (mCollectionType.find(p.collection) != mCollectionType.end()) + if (mCollectionType.find(collection) != mCollectionType.end()) { - subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection); + subs["COLLECTION"] = "&collection_chosen=" + std::string(collection); } else { @@ -182,30 +132,41 @@ void LLFloaterSearch::search(const SearchQuery &p) } } - // add the user's preferred maturity (can be changed via prefs) - std::string maturity; + // Default to PG + std::string maturity = "g"; if (gAgent.prefersAdult()) { - maturity = "gma"; // PG,Mature,Adult + // PG,Mature,Adult + maturity = "gma"; } else if (gAgent.prefersMature()) { - maturity = "gm"; // PG,Mature - } - else - { - maturity = "g"; // PG + // PG,Mature + maturity = "gm"; } subs["MATURITY"] = maturity; - // add the user's god status + // God status subs["GODLIKE"] = gAgent.isGodlike() ? "1" : "0"; - // get the search URL and expand all of the substitutions - // (also adds things like [LANGUAGE], [VERSION], [OS], etc.) - std::string url = gSavedSettings.getString("SearchURL"); + // This call expands a set of generic substitutions like language, viewer version + // etc. and then also does the same with the list of subs passed in. url = LLWeb::expandURLSubstitutions(url, subs); - // and load the URL in the web view - mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + // Naviation to the calculated URL - we know it's HTML so we can + // tell the media system not to bother with the MIME type check. + LLMediaCtrl* search_browser = findChild("search_contents"); + search_browser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); +} + +bool LLFloaterSearch::postBuild() +{ + enableResizeCtrls(true, true, false); + + // This call is actioned by the preload code in llViewerWindow + // that creates the search floater during the login process + // using a generic search with no query + initiateSearch(LLSD()); + + return true; } diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h index beaac2ad2f1..e8a2be4797c 100644 --- a/indra/newview/llfloatersearch.h +++ b/indra/newview/llfloatersearch.h @@ -1,11 +1,10 @@ /** * @file llfloatersearch.h - * @author Martin Reddy - * @brief Search floater - uses an embedded web browser control + * @brief Floater for Search (update 2025, preload) * - * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, 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 @@ -25,70 +24,23 @@ * $/LicenseInfo$ */ -#ifndef LL_LLFLOATERSEARCH_H -#define LL_LLFLOATERSEARCH_H +#pragma once -#include "llfloaterwebcontent.h" -#include "llviewermediaobserver.h" +#include "llfloater.h" -#include +class LLFloaterSearch: + public LLFloater { + friend class LLFloaterReg; -class LLMediaCtrl; + public: + void onOpen(const LLSD& key) override; -/// -/// The search floater allows users to perform all search operations. -/// All search functionality is now implemented via web services and -/// so this floater simply embeds a web view and displays the search -/// web page. The browser control is explicitly marked as "trusted" -/// so that the user can click on teleport links in search results. -/// -class LLFloaterSearch : - public LLFloaterWebContent -{ -public: - struct SearchQuery : public LLInitParam::Block - { - Optional category; - Optional collection; - Optional query; + private: + LLFloaterSearch(const LLSD& key); + ~LLFloaterSearch(); + void initiateSearch(const LLSD& tokens); + bool postBuild() override; - SearchQuery(); - }; - - struct _Params : public LLInitParam::Block<_Params, LLFloaterWebContent::Params> - { - Optional search; - }; - - typedef LLSDParamAdapter<_Params> Params; - - LLFloaterSearch(const Params& key); - - /// show the search floater with a new search - /// see search() for details on the key parameter. - /*virtual*/ void onOpen(const LLSD& key); - - /*virtual*/ void onClose(bool app_quitting); - - /// perform a search with the specific search term. - /// The key should be a map that can contain the following keys: - /// - "id": specifies the text phrase to search for - /// - "category": one of "all" (default), "people", "places", - /// "events", "groups", "wiki", "destinations", "classifieds" - void search(const SearchQuery &query); - - /// changing godmode can affect the search results that are - /// returned by the search website - use this method to tell the - /// search floater that the user has changed god level. - void godLevelChanged(U8 godlevel); - -private: - /*virtual*/ bool postBuild(); - - std::set mSearchType; - std::set mCollectionType; - U8 mSearchGodLevel; + std::set mSearchType; + std::set mCollectionType; }; - -#endif // LL_LLFLOATERSEARCH_H - diff --git a/indra/newview/llfloatertoybox.cpp b/indra/newview/llfloatertoybox.cpp index f6257dbd3da..5e3ec366d56 100644 --- a/indra/newview/llfloatertoybox.cpp +++ b/indra/newview/llfloatertoybox.cpp @@ -63,7 +63,7 @@ bool LLFloaterToybox::postBuild() mToolBar->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3)); mToolBar->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4)); - mToolBar->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4)); + mToolBar->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4,_5)); mToolBar->setButtonEnterCallback(boost::bind(&LLFloaterToybox::onToolBarButtonEnter,this,_1)); // diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index 7651b2528f2..2f1857ec613 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -242,6 +242,16 @@ void LLFloaterURLEntry::getMediaTypeCoro(std::string url, LLHandle pa resolvedMimeType = mimeType; } } + else if (resultHeaders.has(HTTP_IN_HEADER_X_CONTENT_TYPE_OPTIONS)) + { + const std::string& val = resultHeaders[HTTP_IN_HEADER_X_CONTENT_TYPE_OPTIONS]; + if (val == HTTP_NOSNIFF) + { + // Doesn't permit 'sniffing' mime type, default to either html or plain + // If this doesn't work user will have to choose something manually. + resolvedMimeType = HTTP_CONTENT_TEXT_HTML; + } + } floaterUrlEntry->headerFetchComplete(status.getType(), resolvedMimeType); diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index d8b3f996aa5..3e4aadc3815 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -45,7 +45,9 @@ #include "llworld.h" #include "tinygltf/tiny_gltf.h" -#include + +#include +#include #include @@ -357,6 +359,7 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L { if (asset_id.isNull() || override_json.empty()) { + // If there is no asset, there can't be an override queueApply(obj, side, asset_id); } else @@ -369,6 +372,7 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L { if (asset_id.isNull() || material_override == nullptr) { + // If there is no asset, there can't be an override queueApply(obj, side, asset_id); } else @@ -468,7 +472,7 @@ void LLGLTFMaterialList::flushUpdatesOnce(std::shared_ptr callba { data[i]["gltf_json"] = e.override_data->asJSON(); } - if (!e.override_json.empty()) + else if (!e.override_json.empty()) { data[i]["gltf_json"] = e.override_json; } @@ -555,8 +559,7 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp LLSD asset; // read file into buffer - std::istrstream str(&buffer[0], static_cast(buffer.size())); - + boost::iostreams::stream str(buffer.data(), buffer.size()); if (LLSDSerialize::deserialize(asset, str, buffer.size())) { if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString())) diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index da1f1a466f7..5a6e9565aec 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -523,12 +523,12 @@ bool LLGLTFPreviewTexture::render() gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap); gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap); gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap, /*use_history = */ false); - gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap); + gPipeline.gammaCorrect(&screen, &gPipeline.mPostPingMap); LLVertexBuffer::unbind(); - gPipeline.generateGlow(&gPipeline.mPostMap); - gPipeline.combineGlow(&gPipeline.mPostMap, &screen); - gPipeline.renderDoF(&screen, &gPipeline.mPostMap); - gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); + gPipeline.generateGlow(&gPipeline.mPostPingMap); + gPipeline.combineGlow(&gPipeline.mPostPingMap, &screen); + gPipeline.renderDoF(&screen, &gPipeline.mPostPingMap); + gPipeline.applyFXAA(&gPipeline.mPostPingMap, &screen); // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame) gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index 675a8dfe7dc..0f3e220ae08 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -92,6 +92,7 @@ void LLHeroProbeManager::update() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("hero manager update"); llassert(!gCubeSnapshot); // assert a snapshot is not in progress if (LLAppViewer::instance()->logoutRequestSent()) { @@ -293,6 +294,9 @@ void LLHeroProbeManager::renderProbes() // In effect this simulates single-bounce lighting. void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("hero probe update"); + // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mHeroProbeRT; @@ -363,7 +367,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool for (int i = 0; i < mMipChain.size(); ++i) { - LL_PROFILE_GPU_ZONE("probe mip"); + LL_PROFILE_GPU_ZONE("hero probe mip"); mMipChain[i].bindTarget(); if (i == 0) { @@ -390,7 +394,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool if (mip >= 0) { - LL_PROFILE_GPU_ZONE("probe mip copy"); + LL_PROFILE_GPU_ZONE("hero probe mip copy"); mTexture->bind(0); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); @@ -438,7 +442,7 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) for (int i = 0; i < mMipChain.size() / 4; ++i) { - LL_PROFILE_GPU_ZONE("probe radiance gen"); + LL_PROFILE_GPU_ZONE("hero probe radiance gen"); static LLStaticHashedString sMipLevel("mipLevel"); static LLStaticHashedString sRoughness("roughness"); static LLStaticHashedString sWidth("u_width"); @@ -485,6 +489,7 @@ void LLHeroProbeManager::updateUniforms() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("hpmu - uniforms") LLMatrix4a modelview; modelview.loadu(gGLModelView); diff --git a/indra/newview/llhudeffectresetskeleton.cpp b/indra/newview/llhudeffectresetskeleton.cpp index 31065a3e762..2bb5696f593 100644 --- a/indra/newview/llhudeffectresetskeleton.cpp +++ b/indra/newview/llhudeffectresetskeleton.cpp @@ -53,6 +53,15 @@ LLHUDEffectResetSkeleton::~LLHUDEffectResetSkeleton() { } +//----------------------------------------------------------------------------- +// packData() +//----------------------------------------------------------------------------- +void LLHUDEffectResetSkeleton::render() +{ + // HUDEffectResetSkeleton is a fake effect meant to reset skeleton only. + // Just wait for an update() call to do its work and then die. +} + //----------------------------------------------------------------------------- // packData() //----------------------------------------------------------------------------- diff --git a/indra/newview/llhudeffectresetskeleton.h b/indra/newview/llhudeffectresetskeleton.h index 39a61370548..c89516d7fcd 100644 --- a/indra/newview/llhudeffectresetskeleton.h +++ b/indra/newview/llhudeffectresetskeleton.h @@ -38,20 +38,21 @@ class LLHUDEffectResetSkeleton final : public LLHUDEffect public: friend class LLHUDObject; - /*virtual*/ void markDead(); - /*virtual*/ void setSourceObject(LLViewerObject* objectp); + /*virtual*/ void markDead() override; + /*virtual*/ void setSourceObject(LLViewerObject* objectp) override; - void setTargetObject(LLViewerObject *objp); + void setTargetObject(LLViewerObject *objp) override; void setResetAnimations(bool enable){ mResetAnimations = enable; }; protected: LLHUDEffectResetSkeleton(const U8 type); ~LLHUDEffectResetSkeleton(); - /*virtual*/ void packData(LLMessageSystem *mesgsys); - /*virtual*/ void unpackData(LLMessageSystem *mesgsys, S32 blocknum); + void render() override; + void packData(LLMessageSystem *mesgsys) override; + void unpackData(LLMessageSystem *mesgsys, S32 blocknum) override; - void update(); + void update() override; private: bool mResetAnimations; }; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index d1fd82a7f19..e6b33453d51 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -3890,6 +3890,31 @@ void LLInventoryAction::fileUploadLocation(const LLUUID& dest_id, const std::str } } +bool LLInventoryAction::isFileUploadLocation(const LLUUID& dest_id, const std::string& action) +{ + if (action == "def_model") + { + return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_OBJECT) == dest_id; + } + else if (action == "def_texture") + { + return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE) == dest_id; + } + else if (action == "def_sound") + { + return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_SOUND) == dest_id; + } + else if (action == "def_animation") + { + return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_ANIMATION) == dest_id; + } + else if (action == "def_pbr_material") + { + return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL) == dest_id; + } + return false; +} + void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle root) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index ae7bb8770d5..77a2a188773 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -653,6 +653,7 @@ struct LLInventoryAction static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle root); static void removeItemFromDND(LLFolderView* root); static void fileUploadLocation(const LLUUID& dest_id, const std::string& action); + static bool isFileUploadLocation(const LLUUID& dest_id, const std::string& action); static void saveMultipleTextures(const std::vector& filenames, std::set selected_items, LLInventoryModel* model); diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 7212c4dedb4..e129a1296a3 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -110,6 +110,7 @@ LLContextMenu* LLInventoryGalleryContextMenu::createMenu() registrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, uuids, gFloaterView->getParentFloater(mGallery))); enable_registrar.add("Inventory.CanSetUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::canSetUploadLocation, this, _2)); + enable_registrar.add("Inventory.FileUploadLocation.Check", boost::bind(&LLInventoryGalleryContextMenu::isUploadLocationSelected, this, _2)); enable_registrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl*, const LLSD&) { @@ -489,6 +490,12 @@ void LLInventoryGalleryContextMenu::fileUploadLocation(const LLSD& userdata) LLInventoryAction::fileUploadLocation(mUUIDs.front(), param); } +bool LLInventoryGalleryContextMenu::isUploadLocationSelected(const LLSD& userdata) +{ + const std::string param = userdata.asString(); + return LLInventoryAction::isFileUploadLocation(mUUIDs.front(), param); +} + bool LLInventoryGalleryContextMenu::canSetUploadLocation(const LLSD& userdata) { if (mUUIDs.size() != 1) diff --git a/indra/newview/llinventorygallerymenu.h b/indra/newview/llinventorygallerymenu.h index 7c3545432b1..e90c7a19d25 100644 --- a/indra/newview/llinventorygallerymenu.h +++ b/indra/newview/llinventorygallerymenu.h @@ -47,6 +47,7 @@ class LLInventoryGalleryContextMenu : public LLListContextMenu void updateMenuItemsVisibility(LLContextMenu* menu); void fileUploadLocation(const LLSD& userdata); + bool isUploadLocationSelected(const LLSD& userdata); bool canSetUploadLocation(const LLSD& userdata); static void onRename(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index cfa37cc3ee2..73cc9536920 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -40,6 +40,10 @@ #include "llinventorymodel.h" #include "llviewerinventory.h" +bool LLInventoryItemsList::sListIdleRegistered = false; +LLInventoryItemsList::all_list_t LLInventoryItemsList::sAllLists; +LLInventoryItemsList::all_list_t::iterator LLInventoryItemsList::sAllListIter; + LLInventoryItemsList::Params::Params() {} @@ -55,13 +59,39 @@ LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p setNoFilteredItemsMsg(LLTrans::getString("InventoryNoMatchingItems")); - gIdleCallbacks.addFunction(idle, this); + sAllLists.push_back(this); + sAllListIter = sAllLists.begin(); + + if (!sListIdleRegistered) + { + sAllListIter = sAllLists.begin(); + gIdleCallbacks.addFunction(idle, nullptr); + + LLEventPumps::instance().obtain("LLApp").listen( + "LLInventoryItemsList", + [](const LLSD& stat) + { + std::string status(stat["status"]); + if (status != "running") + { + // viewer is starting shutdown + gIdleCallbacks.deleteFunction(idle, nullptr); + } + return false; + }); + sListIdleRegistered = true; + } } // virtual LLInventoryItemsList::~LLInventoryItemsList() { - gIdleCallbacks.deleteFunction(idle, this); + auto it = std::find(sAllLists.begin(), sAllLists.end(), this); + if (it != sAllLists.end()) + { + sAllLists.erase(it); + sAllListIter = sAllLists.begin(); + } } void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array) @@ -111,25 +141,55 @@ void LLInventoryItemsList::updateSelection() mSelectTheseIDs.clear(); } -void LLInventoryItemsList::doIdle() +bool LLInventoryItemsList::doIdle() { - if (mRefreshState == REFRESH_COMPLETE) return; + if (mRefreshState == REFRESH_COMPLETE) return true; // done if (isInVisibleChain() || mForceRefresh || !getFilterSubString().empty()) { refresh(); mRefreshCompleteSignal(this, LLSD()); + return false; // keep going } + return true; // done } //static void LLInventoryItemsList::idle(void* user_data) { - LLInventoryItemsList* self = static_cast(user_data); - if ( self ) - { // Do the real idle - self->doIdle(); + if (sAllLists.empty()) + return; + + LL_PROFILE_ZONE_SCOPED; + + using namespace std::chrono; + auto start = steady_clock::now(); + const milliseconds time_limit = milliseconds(3); + const auto end_time = start + time_limit; + S32 max_update_count = 50; + + if (sAllListIter == sAllLists.end()) + { + sAllListIter = sAllLists.begin(); + } + + S32 updated = 0; + while (steady_clock::now() < end_time + && updated < max_update_count + && sAllListIter != sAllLists.end()) + { + LLInventoryItemsList* list = *sAllListIter; + // Refresh is split into multiple separate parts, + // so keep repeating it while there is time, until done. + // Todo: refresh() split is pointless now? + // Or still useful for large folders? + if (list->doIdle()) + { + // Item is done + ++sAllListIter; + updated++; + } } } @@ -141,6 +201,7 @@ void LLInventoryItemsList::refresh() { case REFRESH_ALL: { + LL_PROFILE_ZONE_NAMED("items_refresh_all"); mAddedItems.clear(); mRemovedItems.clear(); computeDifference(getIDs(), mAddedItems, mRemovedItems); @@ -163,6 +224,7 @@ void LLInventoryItemsList::refresh() } case REFRESH_LIST_ERASE: { + LL_PROFILE_ZONE_NAMED("items_refresh_erase"); uuid_vec_t::const_iterator it = mRemovedItems.begin(); for (; mRemovedItems.end() != it; ++it) { @@ -175,6 +237,7 @@ void LLInventoryItemsList::refresh() } case REFRESH_LIST_APPEND: { + LL_PROFILE_ZONE_NAMED("items_refresh_append"); static const unsigned ADD_LIMIT = 25; // Note: affects perfomance unsigned int nadded = 0; @@ -239,6 +302,7 @@ void LLInventoryItemsList::refresh() } case REFRESH_LIST_SORT: { + LL_PROFILE_ZONE_NAMED("items_refresh_sort"); // Filter, sort, rearrange and notify parent about shape changes filterItems(true, true); @@ -255,7 +319,10 @@ void LLInventoryItemsList::refresh() break; } default: - break; + { + mRefreshState = REFRESH_COMPLETE; + break; + } } setForceRefresh(mRefreshState != REFRESH_COMPLETE); diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 9ebeb5e52b0..b20c27eec8b 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -59,7 +59,10 @@ class LLInventoryItemsList : public LLFlatListViewEx * Sets the flag indicating that the list needs to be refreshed even if it is * not currently visible. */ - void setForceRefresh(bool force_refresh) { mForceRefresh = force_refresh; } + void setForceRefresh(bool force_refresh) + { + mForceRefresh = force_refresh; + } /** * If refreshes when invisible. @@ -76,7 +79,7 @@ class LLInventoryItemsList : public LLFlatListViewEx * This is needed for example to filter items of the list hidden by closed * accordion tab. */ - virtual void doIdle(); // Real idle routine + bool doIdle(); // Real idle routine static void idle(void* user_data); // static glue to doIdle() protected: @@ -126,6 +129,12 @@ class LLInventoryItemsList : public LLFlatListViewEx bool mForceRefresh; commit_signal_t mRefreshCompleteSignal; + + // Update synchronization + typedef std::vector all_list_t; + static all_list_t sAllLists; + static all_list_t::iterator sAllListIter; + static bool sListIdleRegistered; }; #endif //LL_LLINVENTORYITEMSLIST_H diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 590cbbec4ec..a935ede1860 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -187,6 +187,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2)); + mEnableCallbackRegistrar.add("Inventory.FileUploadLocation.Check", boost::bind(&LLInventoryPanel::isUploadLocationSelected, this, _2)); mCommitCallbackRegistrar.add("Inventory.OpenNewFolderWindow", boost::bind(&LLInventoryPanel::openSingleViewInventory, this, LLUUID())); } @@ -1832,6 +1833,13 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata) LLInventoryAction::fileUploadLocation(dest, param); } +bool LLInventoryPanel::isUploadLocationSelected(const LLSD& userdata) +{ + const std::string param = userdata.asString(); + const LLUUID dest = LLFolderBridge::sSelf.get()->getUUID(); + return LLInventoryAction::isFileUploadLocation(dest, param); +} + void LLInventoryPanel::openSingleViewInventory(LLUUID folder_id) { LLPanelMainInventory::newFolderWindow(folder_id.isNull() ? LLFolderBridge::sSelf.get()->getUUID() : folder_id); diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 473283352ff..50333709fc6 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -225,6 +225,7 @@ class LLInventoryPanel : public LLPanel void doCreate(const LLSD& userdata); bool beginIMSession(); void fileUploadLocation(const LLSD& userdata); + bool isUploadLocationSelected(const LLSD& userdata); void openSingleViewInventory(LLUUID folder_id = LLUUID()); void purgeSelectedItems(); bool attachObject(const LLSD& userdata); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index e31fbb188a6..a99c9df0ff1 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -196,7 +196,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate) #ifndef LL_WINDOWS const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename)); #else - const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(utf8str_to_utf16str(mFilename))); + const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(ll_convert(mFilename))); #endif LLSD new_last_modified = asctime(localtime(&temp_time)); diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index fab18f2d263..d6facad23da 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -134,7 +134,7 @@ bool LLLocalGLTFMaterial::updateSelf() #ifndef LL_WINDOWS const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename)); #else - const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(utf8str_to_utf16str(mFilename))); + const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(ll_convert(mFilename))); #endif LLSD new_last_modified = asctime(localtime(&temp_time)); diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index fa1f650113a..30ea255e244 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -80,8 +80,8 @@ const static std::string MULTI_LINE_PREFIX(" "); * * Note: "You" was used as an avatar names in viewers of previous versions */ -const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]\\s+|\\[\\d{1,2}:\\d{2}\\]\\s+)?(.*)$"); -const static boost::regex TIMESTAMP("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]|\\[\\d{1,2}:\\d{2}\\]).*"); +const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\s[AaPp][Mm]\\]\\s+|\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]\\s+|\\[\\d{1,2}:\\d{2}\\s[AaPp][Mm]\\]\\s+|\\[\\d{1,2}:\\d{2}\\]\\s+)?(.*)$"); +const static boost::regex TIMESTAMP("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}(\\s[AaPp][Mm])?\\]|\\[\\d{1,2}:\\d{2}(\\s[AaPp][Mm])?\\]).*"); /** * Regular expression suitable to match names like @@ -152,6 +152,10 @@ class LLLogChatTimeScanner: public LLSingleton void checkAndCutOffDate(std::string& time_str) { + if (time_str.size() < 10) // not enough space for a date + { + return; + } // Cuts off the "%Y/%m/%d" from string for todays timestamps. // Assume that passed string has at least "%H:%M" time format. date log_date(not_a_date_time); @@ -168,20 +172,12 @@ class LLLogChatTimeScanner: public LLSingleton if ( days_alive == zero_days ) { - // Yep, today's so strip "%Y/%m/%d" info - ptime stripped_time(not_a_date_time); - - mTimeStream.str(LLStringUtil::null); - mTimeStream << time_str; - mTimeStream >> stripped_time; - mTimeStream.clear(); - - time_str.clear(); - - mTimeStream.str(LLStringUtil::null); - mTimeStream << stripped_time; - mTimeStream >> time_str; - mTimeStream.clear(); + size_t pos = time_str.find_first_of(' '); + if (pos != std::string::npos) + { + time_str.erase(0, pos + 1); + LLStringUtil::trim(time_str); + } } LL_DEBUGS("LLChatLogParser") @@ -310,16 +306,22 @@ std::string LLLogChat::timestamp2LogString(U32 timestamp, bool withdate) std::string timeStr; if (withdate) { - timeStr = "[" + LLTrans::getString ("TimeYear") + "]/[" - + LLTrans::getString ("TimeMonth") + "]/[" - + LLTrans::getString ("TimeDay") + "] [" - + LLTrans::getString ("TimeHour") + "]:[" - + LLTrans::getString ("TimeMin") + "]"; + timeStr = "[" + LLTrans::getString("TimeYear") + "]/[" + + LLTrans::getString("TimeMonth") + "]/[" + + LLTrans::getString("TimeDay") + "] "; + } + + static bool use_24h = gSavedSettings.getBOOL("Use24HourClock"); + if (use_24h) + { + timeStr += "[" + LLTrans::getString("TimeHour") + "]:[" + + LLTrans::getString("TimeMin") + "]"; } else { - timeStr = "[" + LLTrans::getString("TimeHour") + "]:[" - + LLTrans::getString ("TimeMin")+"]"; + timeStr += "[" + LLTrans::getString("TimeHour12") + "]:[" + + LLTrans::getString("TimeMin") + "] [" + + LLTrans::getString("TimeAMPM") + "]"; } LLSD substitution; diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 4bffe7feac8..41cec4f074e 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -62,7 +62,7 @@ const S32 LOGIN_MAX_RETRIES = 0; // Viewer should not autmatically retry login const F32 LOGIN_SRV_TIMEOUT_MIN = 10; -const F32 LOGIN_SRV_TIMEOUT_MAX = 120; +const F32 LOGIN_SRV_TIMEOUT_MAX = 180; const F32 LOGIN_DNS_TIMEOUT_FACTOR = 0.9; // make DNS wait shorter then retry time class LLLoginInstance::Disposable { diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp index aa030013891..51c38aba3ac 100644 --- a/indra/newview/llmachineid.cpp +++ b/indra/newview/llmachineid.cpp @@ -293,7 +293,7 @@ bool LLWMIMethods::getGenericSerialNumber(const BSTR &select, const LPCWSTR &var if (validate_as_uuid) { std::wstring ws(serialNumber, serial_size); - std::string str = ll_convert_wide_to_string(ws); + std::string str = ll_convert(ws); if (!LLUUID::validate(str)) { @@ -315,7 +315,7 @@ bool LLWMIMethods::getGenericSerialNumber(const BSTR &select, const LPCWSTR &var continue; } } - LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL; + LL_INFOS("AppInit") << " Serial Number : " << ll_convert_wide_to_string(std::wstring(vtProp.bstrVal, SysStringLen(vtProp.bstrVal))) << LL_ENDL; unsigned int j = 0; diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 3e5d6d1171c..cac72bb0858 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -63,8 +63,9 @@ #include "tinygltf/tiny_gltf.h" #include "lltinygltfhelper.h" -#include +#include +#include const std::string MATERIAL_BASE_COLOR_DEFAULT_NAME = "Base Color"; const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; @@ -1246,7 +1247,7 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) { LLSD asset; - std::istrstream str(&buffer[0], buffer.size()); + boost::iostreams::stream str(buffer.data(), buffer.size()); if (LLSDSerialize::deserialize(asset, str, buffer.size())) { if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString())) diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 202008f7f93..c7b60b2fd56 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -347,6 +347,7 @@ bool LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) { LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this)); + registar.add("Open.ShowSource", boost::bind(&LLMediaCtrl::onShowSource, this)); // stinson 05/05/2014 : use this as the parent of the context menu if the static menu // container has yet to be created @@ -364,8 +365,9 @@ bool LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) { // hide/show debugging options bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging"); + menu->setItemVisible("debug_separator", media_plugin_debugging_enabled); menu->setItemVisible("open_webinspector", media_plugin_debugging_enabled ); - menu->setItemVisible("debug_separator", media_plugin_debugging_enabled ); + menu->setItemVisible("show_page_source", media_plugin_debugging_enabled); menu->show(x, y); LLMenuGL::showPopup(this, menu, x, y); @@ -444,6 +446,12 @@ void LLMediaCtrl::onOpenWebInspector() mMediaSource->getMediaPlugin()->showWebInspector( true ); } +void LLMediaCtrl::onShowSource() +{ + if (mMediaSource && mMediaSource->hasMedia()) + mMediaSource->getMediaPlugin()->showPageSource(); +} + //////////////////////////////////////////////////////////////////////////////// // bool LLMediaCtrl::handleKeyHere( KEY key, MASK mask ) diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 9f9564af46c..a644ef30719 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -171,6 +171,7 @@ class LLMediaCtrl : // right click debugging item void onOpenWebInspector(); + void onShowSource(); LLUUID getTextureID() {return mMediaTextureID;} diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 9e8ed3bb437..e0f942b083a 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2310,6 +2310,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes } if (request_skin) { + LLMutexLock lock(mMutex); mSkinRequests.push_back(UUIDBasedRequest(mesh_id)); } } @@ -2460,7 +2461,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat LLPointer info = nullptr; info = new LLMeshSkinInfo(mesh_id, skin); - if (isAgentAvatarValid()) + if (isAgentAvatarValid() && gAgentAvatarp->mInitFlags != 0) { // joint numbers are consistent inside LLVOAvatar and animations, but inconsistent inside meshes, // generate a map of mesh joint numbers to LLVOAvatar joint numbers LLSkinningUtil::initJointNums(info, gAgentAvatarp); @@ -2569,7 +2570,7 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_ return MESH_OK; } -LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, const LLMeshUploadThread::lod_sources_map_t& sources_list, +LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list_t& data, const LLMeshUploadThread::lod_sources_map_t& sources_list, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, const std::string & upload_url, LLUUID destination_folder_id, bool do_upload, @@ -2651,7 +2652,7 @@ void LLMeshUploadThread::DecompRequest::completed() void LLMeshUploadThread::preStart() { //build map of LLModel refs to instances for callbacks - for (instance_list::iterator iter = mInstanceList.begin(); iter != mInstanceList.end(); ++iter) + for (instance_list_t::iterator iter = mInstanceList.begin(); iter != mInstanceList.end(); ++iter) { mInstance[iter->mModel].push_back(*iter); } @@ -2700,6 +2701,179 @@ LLSD llsd_from_file(std::string filename) return result; } +void LLMeshUploadThread::packModelIntance( + LLModel* model, + LLMeshUploadThread::instance_list_t& instance_list, + std::string& model_name, + LLSD& res, + S32& mesh_num, + S32& texture_num, + S32& instance_num, + std::unordered_set& textures, + std::unordered_map texture_index, + std::unordered_map& mesh_index, + std::vector& texture_list_dest, + bool include_textures + ) +{ + LLMeshUploadData data; + data.mBaseModel = model; + + LLModelInstance& first_instance = *(instance_list.begin()); + for (S32 i = 0; i < 5; i++) + { + data.mModel[i] = first_instance.mLOD[i]; + } + + if (mesh_index.find(data.mBaseModel) == mesh_index.end()) + { + // Have not seen this model before - create a new mesh_list entry for it. + if (model_name.empty()) + { + model_name = data.mBaseModel->getName(); + } + + std::stringstream ostr; + + LLModel::Decomposition& decomp = + data.mModel[LLModel::LOD_PHYSICS].notNull() ? + data.mModel[LLModel::LOD_PHYSICS]->mPhysics : + data.mBaseModel->mPhysics; + + decomp.mBaseHull = mHullMap[data.mBaseModel]; + + LLSD mesh_header = LLModel::writeModel( + ostr, + data.mModel[LLModel::LOD_PHYSICS], + data.mModel[LLModel::LOD_HIGH], + data.mModel[LLModel::LOD_MEDIUM], + data.mModel[LLModel::LOD_LOW], + data.mModel[LLModel::LOD_IMPOSTOR], + decomp, + mUploadSkin, + mUploadJoints, + mLockScaleIfJointPosition, + LLModel::WRITE_BINARY, + false, + data.mBaseModel->mSubmodelID); + + data.mAssetData = ostr.str(); + std::string str = ostr.str(); + + res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(), str.end()); + mesh_index[data.mBaseModel] = mesh_num; + mesh_num++; + } + + // For all instances that use this model + for (instance_list_t::iterator instance_iter = instance_list.begin(); + instance_iter != instance_list.end(); + ++instance_iter) + { + LLModelInstance& instance = *instance_iter; + + LLSD instance_entry; + + for (S32 i = 0; i < 5; i++) + { + data.mModel[i] = instance.mLOD[i]; + } + + LLVector3 pos, scale; + LLQuaternion rot; + LLMatrix4 transformation = instance.mTransform; + decomposeMeshMatrix(transformation, pos, rot, scale); + instance_entry["position"] = ll_sd_from_vector3(pos); + instance_entry["rotation"] = ll_sd_from_quaternion(rot); + instance_entry["scale"] = ll_sd_from_vector3(scale); + + instance_entry["material"] = LL_MCODE_WOOD; + if (model->mSubmodelID) + { + // Should it really be different? + instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_NONE); + } + else + { + instance_entry["physics_shape_type"] = data.mModel[LLModel::LOD_PHYSICS].notNull() ? (U8)(LLViewerObject::PHYSICS_SHAPE_PRIM) : (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); + } + instance_entry["mesh"] = mesh_index[data.mBaseModel]; + instance_entry["mesh_name"] = instance.mLabel; + + instance_entry["face_list"] = LLSD::emptyArray(); + + // We want to be able to allow more than 8 materials... + // + S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), instance.mModel->getNumVolumeFaces()); + + for (S32 face_num = 0; face_num < end; face_num++) + { + // multiple faces can reuse the same material + LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]]; + LLSD face_entry = LLSD::emptyMap(); + + LLViewerFetchedTexture* texture = NULL; + + if (material.mDiffuseMapFilename.size()) + { + texture = FindViewerTexture(material); + } + + if ((texture != NULL) && + (textures.find(texture) == textures.end())) + { + textures.insert(texture); + } + + std::stringstream texture_str; + if (texture != NULL && include_textures && mUploadTextures) + { + if (texture->hasSavedRawImage()) + { + LLImageDataLock lock(texture->getSavedRawImage()); + + LLPointer upload_file = + LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage()); + + if (!upload_file.isNull() && upload_file->getDataSize() && !upload_file->isBufferInvalid()) + { + texture_str.write((const char*)upload_file->getData(), upload_file->getDataSize()); + } + } + } + + if (texture != NULL && + mUploadTextures && + texture_index.find(texture) == texture_index.end()) + { + texture_index[texture] = texture_num; + std::string str = texture_str.str(); + res["texture_list"][texture_num] = LLSD::Binary(str.begin(), str.end()); + // store indexes for error handling; + texture_list_dest.push_back(material.mDiffuseMapFilename); + texture_num++; + } + + // Subset of TextureEntry fields. + if (texture != NULL && mUploadTextures) + { + face_entry["image"] = texture_index[texture]; + face_entry["scales"] = 1.0; + face_entry["scalet"] = 1.0; + face_entry["offsets"] = 0.0; + face_entry["offsett"] = 0.0; + face_entry["imagerot"] = 0.0; + } + face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor); + face_entry["fullbright"] = material.mFullbright; + instance_entry["face_list"][face_num] = face_entry; + } + + res["instance_list"][instance_num] = instance_entry; + instance_num++; + } +} + void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector& texture_list_dest, bool include_textures) { LLSD result; @@ -2733,6 +2907,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector& } S32 mesh_num = 0; S32 texture_num = 0; + S32 instance_num = 0; std::unordered_set textures; std::unordered_map texture_index; @@ -2740,7 +2915,34 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector& std::unordered_map mesh_index; std::string model_name; - S32 instance_num = 0; + // If server gets a m1, m2, m3, m4 list, m1 becomes the root + // and the rest go as m4, m3, m2 + // to counter that mInstance is sorted as m4, m3, m2, m1 + // and we grab m1 from the end and send it first + LLModel* root_model = nullptr; + for (instance_map_t::reverse_iterator iter = mInstance.rbegin(); iter != mInstance.rend(); ++iter) + { + if (iter->first->mSubmodelID) + { + // Submodel can't be root + continue; + } + root_model = iter->first; + packModelIntance( + iter->first, + iter->second, + model_name, + res, + mesh_num, + texture_num, + instance_num, + textures, + texture_index, + mesh_index, + texture_list_dest, + include_textures); + break; + } // Handle models, ignore submodels for now. // Probably should pre-sort by mSubmodelID instead of running twice. @@ -2748,319 +2950,53 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector& // deterministic order. for (auto& iter : mInstance) { - LLMeshUploadData data; - data.mBaseModel = iter.first; - - if (data.mBaseModel->mSubmodelID) + if (iter.first->mSubmodelID) { // These are handled below to insure correct parenting order on creation // due to map walking being based on model address (aka random) continue; } - - LLModelInstance& first_instance = *(iter.second.begin()); - for (S32 i = 0; i < 5; i++) - { - data.mModel[i] = first_instance.mLOD[i]; - } - - if (mesh_index.find(data.mBaseModel) == mesh_index.end()) + if (root_model == iter.first) { - // Have not seen this model before - create a new mesh_list entry for it. - if (model_name.empty()) - { - model_name = data.mBaseModel->getName(); - } - - std::stringstream ostr; - - LLModel::Decomposition& decomp = - data.mModel[LLModel::LOD_PHYSICS].notNull() ? - data.mModel[LLModel::LOD_PHYSICS]->mPhysics : - data.mBaseModel->mPhysics; - - decomp.mBaseHull = mHullMap[data.mBaseModel]; - - LLSD mesh_header = LLModel::writeModel( - ostr, - data.mModel[LLModel::LOD_PHYSICS], - data.mModel[LLModel::LOD_HIGH], - data.mModel[LLModel::LOD_MEDIUM], - data.mModel[LLModel::LOD_LOW], - data.mModel[LLModel::LOD_IMPOSTOR], - decomp, - mUploadSkin, - mUploadJoints, - mLockScaleIfJointPosition, - LLModel::WRITE_BINARY, - false, - data.mBaseModel->mSubmodelID); - - data.mAssetData = ostr.str(); - std::string str = ostr.str(); - - res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end()); - mesh_index[data.mBaseModel] = mesh_num; - mesh_num++; - } - - // For all instances that use this model - for (instance_list::iterator instance_iter = iter.second.begin(); - instance_iter != iter.second.end(); - ++instance_iter) - { - - LLModelInstance& instance = *instance_iter; - - LLSD instance_entry; - - for (S32 i = 0; i < 5; i++) - { - data.mModel[i] = instance.mLOD[i]; - } - - LLVector3 pos, scale; - LLQuaternion rot; - LLMatrix4 transformation = instance.mTransform; - decomposeMeshMatrix(transformation,pos,rot,scale); - instance_entry["position"] = ll_sd_from_vector3(pos); - instance_entry["rotation"] = ll_sd_from_quaternion(rot); - instance_entry["scale"] = ll_sd_from_vector3(scale); - - instance_entry["material"] = LL_MCODE_WOOD; - instance_entry["physics_shape_type"] = data.mModel[LLModel::LOD_PHYSICS].notNull() ? (U8)(LLViewerObject::PHYSICS_SHAPE_PRIM) : (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); - instance_entry["mesh"] = mesh_index[data.mBaseModel]; - instance_entry["mesh_name"] = instance.mLabel; - - instance_entry["face_list"] = LLSD::emptyArray(); - - // We want to be able to allow more than 8 materials... - // - S32 end = llmin((S32)data.mBaseModel->mMaterialList.size(), instance.mModel->getNumVolumeFaces()) ; - - for (S32 face_num = 0; face_num < end; face_num++) - { - // multiple faces can reuse the same material - LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]]; - LLSD face_entry = LLSD::emptyMap(); - - LLViewerFetchedTexture *texture = NULL; - - if (material.mDiffuseMapFilename.size()) - { - texture = FindViewerTexture(material); - } - - if ((texture != NULL) && - (textures.find(texture) == textures.end())) - { - textures.insert(texture); - } - - std::stringstream texture_str; - if (texture != NULL && include_textures && mUploadTextures) - { - if (texture->hasSavedRawImage()) - { - LLImageDataLock lock(texture->getSavedRawImage()); - - LLPointer upload_file = - LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage()); - - if (!upload_file.isNull() && upload_file->getDataSize() && !upload_file->isBufferInvalid()) - { - texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize()); - } - } - } - - if (texture != NULL && - mUploadTextures && - texture_index.find(texture) == texture_index.end()) - { - texture_index[texture] = texture_num; - std::string str = texture_str.str(); - res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end()); - // store indexes for error handling; - texture_list_dest.push_back(material.mDiffuseMapFilename); - texture_num++; - } - - // Subset of TextureEntry fields. - if (texture != NULL && mUploadTextures) - { - face_entry["image"] = texture_index[texture]; - face_entry["scales"] = 1.0; - face_entry["scalet"] = 1.0; - face_entry["offsets"] = 0.0; - face_entry["offsett"] = 0.0; - face_entry["imagerot"] = 0.0; - } - face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor); - face_entry["fullbright"] = material.mFullbright; - instance_entry["face_list"][face_num] = face_entry; - } - - res["instance_list"][instance_num] = instance_entry; - instance_num++; + // Reached root, root was already packed and is last non-submodel + break; } + packModelIntance( + iter.first, + iter.second, + model_name, + res, + mesh_num, + texture_num, + instance_num, + textures, + texture_index, + mesh_index, + texture_list_dest, + include_textures); } // Now handle the submodels. for (auto& iter : mInstance) { - LLMeshUploadData data; - data.mBaseModel = iter.first; - - if (!data.mBaseModel->mSubmodelID) + if (!iter.first->mSubmodelID) { // These were handled above already... - // continue; } - - LLModelInstance& first_instance = *(iter.second.begin()); - for (S32 i = 0; i < 5; i++) - { - data.mModel[i] = first_instance.mLOD[i]; - } - - if (mesh_index.find(data.mBaseModel) == mesh_index.end()) - { - // Have not seen this model before - create a new mesh_list entry for it. - if (model_name.empty()) - { - model_name = data.mBaseModel->getName(); - } - - std::stringstream ostr; - - LLModel::Decomposition& decomp = - data.mModel[LLModel::LOD_PHYSICS].notNull() ? - data.mModel[LLModel::LOD_PHYSICS]->mPhysics : - data.mBaseModel->mPhysics; - - decomp.mBaseHull = mHullMap[data.mBaseModel]; - - LLSD mesh_header = LLModel::writeModel( - ostr, - data.mModel[LLModel::LOD_PHYSICS], - data.mModel[LLModel::LOD_HIGH], - data.mModel[LLModel::LOD_MEDIUM], - data.mModel[LLModel::LOD_LOW], - data.mModel[LLModel::LOD_IMPOSTOR], - decomp, - mUploadSkin, - mUploadJoints, - mLockScaleIfJointPosition, - LLModel::WRITE_BINARY, - false, - data.mBaseModel->mSubmodelID); - - data.mAssetData = ostr.str(); - std::string str = ostr.str(); - - res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end()); - mesh_index[data.mBaseModel] = mesh_num; - mesh_num++; - } - - // For all instances that use this model - for (instance_list::iterator instance_iter = iter.second.begin(); - instance_iter != iter.second.end(); - ++instance_iter) - { - - LLModelInstance& instance = *instance_iter; - - LLSD instance_entry; - - for (S32 i = 0; i < 5; i++) - { - data.mModel[i] = instance.mLOD[i]; - } - - LLVector3 pos, scale; - LLQuaternion rot; - LLMatrix4 transformation = instance.mTransform; - decomposeMeshMatrix(transformation,pos,rot,scale); - instance_entry["position"] = ll_sd_from_vector3(pos); - instance_entry["rotation"] = ll_sd_from_quaternion(rot); - instance_entry["scale"] = ll_sd_from_vector3(scale); - - instance_entry["material"] = LL_MCODE_WOOD; - instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_NONE); - instance_entry["mesh"] = mesh_index[data.mBaseModel]; - - instance_entry["face_list"] = LLSD::emptyArray(); - - // We want to be able to allow more than 8 materials... - // - S32 end = llmin((S32)instance.mMaterial.size(), instance.mModel->getNumVolumeFaces()) ; - - for (S32 face_num = 0; face_num < end; face_num++) - { - LLImportMaterial& material = instance.mMaterial[data.mBaseModel->mMaterialList[face_num]]; - LLSD face_entry = LLSD::emptyMap(); - - LLViewerFetchedTexture *texture = NULL; - - if (material.mDiffuseMapFilename.size()) - { - texture = FindViewerTexture(material); - } - - if ((texture != NULL) && - (textures.find(texture) == textures.end())) - { - textures.insert(texture); - } - - std::stringstream texture_str; - if (texture != NULL && include_textures && mUploadTextures) - { - if (texture->hasSavedRawImage()) - { - LLImageDataLock lock(texture->getSavedRawImage()); - - LLPointer upload_file = - LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage()); - - if (!upload_file.isNull() && upload_file->getDataSize()) - { - texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize()); - } - } - } - - if (texture != NULL && - mUploadTextures && - texture_index.find(texture) == texture_index.end()) - { - texture_index[texture] = texture_num; - std::string str = texture_str.str(); - res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end()); - texture_num++; - } - - // Subset of TextureEntry fields. - if (texture != NULL && mUploadTextures) - { - face_entry["image"] = texture_index[texture]; - face_entry["scales"] = 1.0; - face_entry["scalet"] = 1.0; - face_entry["offsets"] = 0.0; - face_entry["offsett"] = 0.0; - face_entry["imagerot"] = 0.0; - } - face_entry["diffuse_color"] = ll_sd_from_color4(material.mDiffuseColor); - face_entry["fullbright"] = material.mFullbright; - instance_entry["face_list"][face_num] = face_entry; - } - - res["instance_list"][instance_num] = instance_entry; - instance_num++; - } + packModelIntance( + iter.first, + iter.second, + model_name, + res, + mesh_num, + texture_num, + instance_num, + textures, + texture_index, + mesh_index, + texture_list_dest, + include_textures); } if (model_name.empty()) model_name = "mesh model"; @@ -3076,7 +3012,7 @@ void LLMeshUploadThread::generateHulls() { bool has_valid_requests = false ; - for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) + for (instance_map_t::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) { LLMeshUploadData data; data.mBaseModel = iter->first; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index ab17b921d6c..450afd5d5a9 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -668,11 +668,11 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler LLPointer mFinalDecomp; volatile bool mPhysicsComplete; - typedef std::map, std::vector > hull_map; - hull_map mHullMap; + typedef std::map, std::vector > hull_map_t; + hull_map_t mHullMap; - typedef std::vector instance_list; - instance_list mInstanceList; + typedef std::vector instance_list_t; + instance_list_t mInstanceList; // Upload should happen in deterministic order, so sort instances by model name. struct LLUploadModelInstanceLess @@ -686,11 +686,11 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler } // Note: probably can sort by mBaseModel->mSubmodelID here as well to avoid // running over the list twice in wholeModelToLLSD. - return a->mLabel < b->mLabel; + return a->mLabel > b->mLabel; } }; - typedef std::map, instance_list, LLUploadModelInstanceLess> instance_map; - instance_map mInstance; + typedef std::map, instance_list_t, LLUploadModelInstanceLess> instance_map_t; + instance_map_t mInstance; typedef std::map lod_sources_map_t; lod_sources_map_t mLodSources; @@ -709,7 +709,7 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler std::string mWholeModelUploadURL; LLUUID mDestinationFolderId; - LLMeshUploadThread(instance_list& data, const lod_sources_map_t& sources_list, + LLMeshUploadThread(instance_list_t& data, const lod_sources_map_t& sources_list, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, const std::string & upload_url, @@ -745,6 +745,22 @@ class LLMeshUploadThread : public LLThread, public LLCore::HttpHandler static LLViewerFetchedTexture* FindViewerTexture(const LLImportMaterial& material); +protected: + void packModelIntance( + LLModel* model, + LLMeshUploadThread::instance_list_t& instance_list, + std::string& model_name, + LLSD& res, + S32& mesh_num, + S32& texture_num, + S32& instance_num, + std::unordered_set &textures, + std::unordered_map texture_index, + std::unordered_map& mesh_index, + std::vector& texture_list_dest, + bool include_textures + ); + private: LLHandle mFeeObserverHandle; LLHandle mUploadObserverHandle; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index e0649e1d88b..46411fc4a03 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -576,7 +576,7 @@ void LLModelPreview::rebuildUploadData() for (U32 model_ind = 0; model_ind < mModel[lod].size(); ++model_ind) { bool found_model = false; - for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) { LLModelInstance& instance = *iter; if (instance.mLOD[lod] == mModel[lod][model_ind]) @@ -2209,7 +2209,7 @@ void LLModelPreview::updateStatusMessages() total_submeshes[i] = 0; } - for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) { LLModelInstance& instance = *iter; @@ -3530,7 +3530,7 @@ bool LLModelPreview::render() if (!show_skin_weight) { - for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) { LLModelInstance& instance = *iter; @@ -3616,7 +3616,7 @@ bool LLModelPreview::render() gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) { LLModelInstance& instance = *iter; @@ -3738,7 +3738,7 @@ bool LLModelPreview::render() gGL.diffuseColor4f(1.f, 0.f, 0.f, 1.f); const LLVector4a scale(0.5f); - for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + for (LLMeshUploadThread::instance_list_t::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) { LLModelInstance& instance = *iter; diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 7b3b699b33d..92ac2d1fafa 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -319,7 +319,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex, public LLH // Amount of triangles in original(base) model U32 mMaxTriangleLimit; - LLMeshUploadThread::instance_list mUploadData; + LLMeshUploadThread::instance_list_t mUploadData; std::set mTextureSet; LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList; diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index 5b8b28ebe60..9a33bcb1b96 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -38,6 +38,7 @@ #include "lluicolortable.h" #include "message.h" #include "llnotificationsutil.h" +#include "llviewercontrol.h" #include LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p), @@ -133,10 +134,22 @@ std::string LLNotificationListItem::buildNotificationDate(const LLDate& time_sta default: timeStr = "[" + LLTrans::getString("TimeMonth") + "]/[" +LLTrans::getString("TimeDay")+"]/[" - +LLTrans::getString("TimeYear")+"] [" - +LLTrans::getString("TimeHour")+"]:[" - +LLTrans::getString("TimeMin")+"] [" - +LLTrans::getString("TimeTimezone")+"]"; + +LLTrans::getString("TimeYear")+"] ["; + + static bool use_24h = gSavedSettings.getBOOL("Use24HourClock"); + if (use_24h) + { + timeStr += LLTrans::getString("TimeHour") + "]:[" + + LLTrans::getString("TimeMin") + "] [" + + LLTrans::getString("TimeTimezone") + "]"; + } + else + { + timeStr += LLTrans::getString("TimeHour12") + "]:[" + + LLTrans::getString("TimeMin") + "] [" + + LLTrans::getString("TimeAMPM") + "] [" + + LLTrans::getString("TimeTimezone") + "]"; + } break; } LLSD substitution; diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 3adee9fa165..8589afae06f 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -818,6 +818,7 @@ void LLOutfitGallery::getCurrentCategories(uuid_vec_t& vcur) void LLOutfitGallery::updateAddedCategory(LLUUID cat_id) { + LL_PROFILE_ZONE_SCOPED; LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); if (!cat) return; diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 4e594af432d..58cd9fab834 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -181,6 +181,7 @@ void LLOutfitsList::onOpen(const LLSD& info) void LLOutfitsList::updateAddedCategory(LLUUID cat_id) { + LL_PROFILE_ZONE_SCOPED; LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); if (!cat) return; @@ -251,7 +252,9 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id) if (AISAPI::isAvailable() && LLInventoryModelBackgroundFetch::instance().folderFetchActive()) { - // for reliability just fetch it whole, linked items included + // For reliability just fetch it whole, linked items included + // Todo: list is not warrantied to exist once callback arrives + // Fix it! LLInventoryModelBackgroundFetch::instance().fetchFolderAndLinks(cat_id, [cat_id, list] { if (list) @@ -1059,6 +1062,7 @@ void LLOutfitListBase::onIdle(void* userdata) void LLOutfitListBase::onIdleRefreshList() { + LL_PROFILE_ZONE_SCOPED; if (LLAppViewer::instance()->quitRequested()) { mRefreshListState.CategoryUUID.setNull(); @@ -1072,7 +1076,7 @@ void LLOutfitListBase::onIdleRefreshList() return; } - const F64 MAX_TIME = 0.05f; + const F64 MAX_TIME = 0.005f; F64 curent_time = LLTimer::getTotalSeconds(); const F64 end_time = curent_time + MAX_TIME; diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index 7910bcb41db..07c7b586fc6 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -60,6 +60,7 @@ #include "llviewerwindow.h" #include "llworld.h" #include "llfloaterperms.h" +#include "llviewerassetupload.h" // // Imported globals @@ -225,7 +226,7 @@ void LLPanelContents::onClickNewScript(void *userdata) { const bool children_ok = true; LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok); - if(object) + if (object) { LLPermissions perm; perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); @@ -239,6 +240,113 @@ void LLPanelContents::onClickNewScript(void *userdata) PERM_MOVE | LLFloaterPerms::getNextOwnerPerms("Scripts")); std::string desc; LLViewerAssetType::generateDescriptionFor(LLAssetType::AT_LSL_TEXT, desc); + + // -------------------------------------------------------------------------------------------------- + // Begin hack + // + // The current state of the server doesn't allow specifying a default script template, + // so we have to update its code immediately after creation instead. + // + // Moreover, _PREHASH_RezScript has more complex server-side logic than _PREHASH_CreateInventoryItem, + // which changes the item's attributes, such as its name and UUID. The simplest way to mitigate this + // is to create a temporary item in the user's inventory, modify it as in create_inventory_item()'s + // callback, and then call _PREHASH_RezScript to move it into the object's inventory. + // + // This temporary workaround should be removed after a server-side fix. + // See https://github.com/secondlife/viewer/issues/3731 for more information. + // + LLViewerRegion* region = object->getRegion(); + if (region && region->simulatorFeaturesReceived()) + { + LLSD simulatorFeatures; + region->getSimulatorFeatures(simulatorFeatures); + if (simulatorFeatures["LuaScriptsEnabled"].asBoolean()) + { + if (std::string::size_type pos = desc.find("lsl2"); pos != std::string::npos) + { + desc.replace(pos, 4, "SLua"); + } + + auto scriptCreationCallback = [object](const LLUUID& inv_item) + { + if (!inv_item.isNull()) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (item) + { + const std::string hello_lua_script = + "function state_entry()\n" + " ll.Say(0, \"Hello, Avatar!\")\n" + "end\n" + "\n" + "function touch_start(total_number)\n" + " ll.Say(0, \"Touched.\")\n" + "end\n" + "\n" + "-- Simulate the state_entry event\n" + "state_entry()\n"; + + auto scriptUploadFinished = [object, item](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) + { + LLPointer new_script = new LLViewerInventoryItem(item); + object->saveScript(new_script, true, true); + + // Delete the temporary item from the user's inventory after rezzing it in the object's inventory + ms_sleep(50); + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_RemoveInventoryItem); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_InventoryData); + msg->addUUIDFast(_PREHASH_ItemID, item->getUUID()); + gAgent.sendReliableMessage(); + + gInventory.deleteObject(item->getUUID()); + gInventory.notifyObservers(); + }; + + std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgent"); + if (!url.empty()) + { + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared( + item->getUUID(), + "luau", + hello_lua_script, + scriptUploadFinished, + nullptr)); + + LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); + } + } + } + }; + LLPointer cb = new LLBoostFuncInventoryCallback(scriptCreationCallback); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_CreateInventoryItem); + msg->nextBlock(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlock(_PREHASH_InventoryBlock); + msg->addU32Fast(_PREHASH_CallbackID, gInventoryCallbacks.registerCB(cb)); + msg->addUUIDFast(_PREHASH_FolderID, gInventory.getRootFolderID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLTransactionID::tnull); + msg->addU32Fast(_PREHASH_NextOwnerMask, PERM_MOVE | PERM_TRANSFER); + msg->addS8Fast(_PREHASH_Type, LLAssetType::AT_LSL_TEXT); + msg->addS8Fast(_PREHASH_InvType, LLInventoryType::IT_LSL); + msg->addU8Fast(_PREHASH_WearableType, NO_INV_SUBTYPE); + msg->addStringFast(_PREHASH_Name, "New Script"); + msg->addStringFast(_PREHASH_Description, desc); + + gAgent.sendReliableMessage(); + return; + } + } + // + // End hack + // -------------------------------------------------------------------------------------------------- + LLPointer new_item = new LLViewerInventoryItem( LLUUID::null, diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index 41373cd7f57..7596c0eba84 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -41,6 +41,7 @@ #include "lllandmarkactions.h" #include "llparcel.h" #include "llslurl.h" +#include "llviewercontrol.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" @@ -326,7 +327,8 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem) } else { - std::string timeStr = getString("acquired_date"); + static bool use_24h = gSavedSettings.getBOOL("Use24HourClock"); + std::string timeStr = use_24h ? getString("acquired_date") : getString("acquired_date_ampm"); LLSD substitution; substitution["datetime"] = (S32) time_utc; LLStringUtil::format (timeStr, substitution); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index b1c8b5f36a1..86071e38e1d 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -645,7 +645,7 @@ void LLPanelPrimMediaControls::updateShape() vert_it = vect_face.begin(); vert_end = vect_face.end(); - glm::mat4 mat; + glm::mat4 mat = glm::identity(); if (!is_hud) { mat = get_current_projection() * get_current_modelview(); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index b77ee2f4395..6ea9cd2b92f 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -859,7 +859,7 @@ void LLPanelProfileSecondLife::resetData() resetLoading(); // Set default image and 1:1 dimensions for it - mSecondLifePic->setValue("Generic_Person_Large"); + mSecondLifePic->setValue(LLUUID()); LLRect imageRect = mSecondLifePicLayout->getRect(); mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth()); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 902412d359d..bfdfa68e01e 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -42,6 +42,7 @@ #include "llnotificationsutil.h" #include "lltextbox.h" #include "lltoggleablemenu.h" +#include "llviewercontrol.h" #include "llviewermenu.h" #include "lllandmarkactions.h" #include "llclipboard.h" @@ -215,8 +216,18 @@ std::string LLTeleportHistoryFlatItem::getTimestamp() // Only show timestamp for today and yesterday if(time_diff < seconds_today + seconds_in_day) { - timestamp = "[" + LLTrans::getString("TimeHour12")+"]:[" - + LLTrans::getString("TimeMin")+"] ["+ LLTrans::getString("TimeAMPM")+"]"; + static bool use_24h = gSavedSettings.getBOOL("Use24HourClock"); + if (use_24h) + { + timestamp = "[" + LLTrans::getString("TimeHour") + "]:[" + + LLTrans::getString("TimeMin") + "]"; + } + else + { + timestamp = "[" + LLTrans::getString("TimeHour12") + "]:[" + + LLTrans::getString("TimeMin") + "] [" + LLTrans::getString("TimeAMPM") + "]"; + } + LLSD substitution; substitution["datetime"] = (S32) date.secondsSinceEpoch(); LLStringUtil::format(timestamp, substitution); diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp index 60877494e75..d8d6bcf5fd5 100644 --- a/indra/newview/llpanelvoicedevicesettings.cpp +++ b/indra/newview/llpanelvoicedevicesettings.cpp @@ -240,13 +240,38 @@ void LLPanelVoiceDeviceSettings::refresh() if(mCtrlInputDevices) { mCtrlInputDevices->removeall(); - mCtrlInputDevices->add(getLocalizedDeviceName(mInputDevice), mInputDevice, ADD_BOTTOM); + auto it = mLocalizedDeviceNames.find(mInputDevice); + if (it != mLocalizedDeviceNames.end()) + { + mCtrlInputDevices->add(getLocalizedDeviceName(mInputDevice), mInputDevice, ADD_BOTTOM); + } + else + { + // Display name generaly doesn't match value. + // Value is an id so it's not nessesary readable, + // might not even be valid (disconnected usb). + // Until we get the data, don't change the device, + // otherwise box might override the control. + // But show a readable placeholder. + // Combo is disabled so it's safe to show + // a placeholder. + mCtrlInputDevices->add(getString("device_not_loaded"), mInputDevice, ADD_BOTTOM); + } mCtrlInputDevices->setValue(mInputDevice); } if(mCtrlOutputDevices) { mCtrlOutputDevices->removeall(); - mCtrlOutputDevices->add(getLocalizedDeviceName(mOutputDevice), mOutputDevice, ADD_BOTTOM); + auto it = mLocalizedDeviceNames.find(mOutputDevice); + if (it != mLocalizedDeviceNames.end()) + { + mCtrlOutputDevices->add(getLocalizedDeviceName(mOutputDevice), mOutputDevice, ADD_BOTTOM); + } + else + { + // Don't change the device, only the label + mCtrlOutputDevices->add(getString("device_not_loaded"), mOutputDevice, ADD_BOTTOM); + } mCtrlOutputDevices->setValue(mOutputDevice); } } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index c2aa4925bd8..b3e53df6d88 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -53,6 +53,7 @@ #include "llslider.h" #include "lltooldraganddrop.h" #include "llfilesystem.h" +#include "lllogchat.h" #include "llagent.h" #include "llmenugl.h" @@ -64,22 +65,12 @@ #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" -#include "llkeyboard.h" -#include "llscrollcontainer.h" -#include "llcheckboxctrl.h" #include "llscripteditor.h" -#include "llselectmgr.h" -#include "lltooldraganddrop.h" -#include "llscrolllistctrl.h" #include "lltextbox.h" -#include "llslider.h" -#include "lldir.h" -#include "llcombobox.h" #include "llviewerstats.h" #include "llviewerwindow.h" #include "lluictrlfactory.h" #include "llmediactrl.h" -#include "lluictrlfactory.h" #include "lltrans.h" #include "llviewercontrol.h" #include "llappviewer.h" @@ -90,20 +81,10 @@ #include "lltoggleablemenu.h" #include "llmenubutton.h" #include "llinventoryfunctions.h" +#include "llwebsocketmgr.h" +#include "llscripteditorws.h" +#include -const std::string HELLO_LSL = - "default\n" - "{\n" - " state_entry()\n" - " {\n" - " llSay(0, \"Hello, Avatar!\");\n" - " }\n" - "\n" - " touch_start(integer total_number)\n" - " {\n" - " llSay(0, \"Touched.\");\n" - " }\n" - "}\n"; const std::string HELP_LSL_PORTAL_TOPIC = "LSL_Portal"; const std::string DEFAULT_SCRIPT_NAME = "New Script"; // *TODO:Translate? @@ -119,6 +100,42 @@ static bool have_script_upload_cap(LLUUID& object_id) return object && (! object->getRegion()->getCapability("UpdateScriptTask").empty()); } +static bool have_lua_enabled(const LLUUID& object_id) +{ + LLViewerRegion* region = nullptr; + LLViewerObject* object = gObjectList.findObject(object_id); + if (object) + { + region = object->getRegion(); + } + else + { + region = gAgent.getRegion(); + } + + if (region && region->simulatorFeaturesReceived()) + { + LLSD simulatorFeatures; + region->getSimulatorFeatures(simulatorFeatures); + return simulatorFeatures["LuaScriptsEnabled"].asBoolean(); + } + + return false; +} + +// TEMPORARY: Quick check to see if the code is Lua +// since we don't have another way to determine the language yet +static bool is_lua_script(const std::string& code) +{ + // Check for LSL's signature "default" state pattern + std::regex lsl_pattern("\\s*default\\s*\\{"); + if (std::regex_search(code, lsl_pattern)) + return false; + + // "default" state not found, assuming it's Lua + return true; +} + /// --------------------------------------------------------------------------- /// LLLiveLSLFile /// --------------------------------------------------------------------------- @@ -373,9 +390,9 @@ LLScriptEdCore::LLScriptEdCore( LLScriptEdContainer* container, const std::string& sample, const LLHandle& floater_handle, - void (*load_callback)(void*), - void (*save_callback)(void*, bool), - void (*search_replace_callback) (void* userdata), + script_ed_callback_t load_callback, + save_callback_t save_callback, + script_ed_callback_t search_replace_callback, void* userdata, bool live, S32 bottom_pad) @@ -391,7 +408,6 @@ LLScriptEdCore::LLScriptEdCore( mLastHelpToken(NULL), mLiveHelpHistorySize(0), mEnableSave(false), - mLiveFile(NULL), mLive(live), mContainer(container), mHasScriptData(false), @@ -423,7 +439,6 @@ LLScriptEdCore::~LLScriptEdCore() } } - delete mLiveFile; if (mSyntaxIDConnection.connected()) { mSyntaxIDConnection.disconnect(); @@ -441,42 +456,37 @@ void LLLiveLSLEditor::experienceChanged() } } -void LLLiveLSLEditor::onViewProfile( LLUICtrl *ui, void* userdata ) +void LLLiveLSLEditor::onViewProfile() { - LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; - - LLUUID id; - if(self->mExperienceEnabled->get()) + if (mExperienceEnabled->get()) { - id=self->mScriptEd->getAssociatedExperience(); - if(id.notNull()) + LLUUID id = mScriptEd->getAssociatedExperience(); + if (id.notNull()) { LLFloaterReg::showInstance("experience_profile", id, true); } } - } -void LLLiveLSLEditor::onToggleExperience( LLUICtrl *ui, void* userdata ) +void LLLiveLSLEditor::onToggleExperience() { - LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; - LLUUID id; - if(self->mExperienceEnabled->get()) + if (mExperienceEnabled->get()) { - if(self->mScriptEd->getAssociatedExperience().isNull()) + if (mScriptEd->getAssociatedExperience().isNull()) { - id=self->mExperienceIds.beginArray()->asUUID(); + id = mExperienceIds.beginArray()->asUUID(); } } - if(id != self->mScriptEd->getAssociatedExperience()) + if (id != mScriptEd->getAssociatedExperience()) { - self->mScriptEd->enableSave(self->getIsModifiable()); + mScriptEd->enableSave(getIsModifiable()); } - self->mScriptEd->setAssociatedExperience(id); - self->updateExperiencePanel(); + mScriptEd->setAssociatedExperience(id); + + updateExperiencePanel(); } bool LLScriptEdCore::postBuild() @@ -501,6 +511,7 @@ bool LLScriptEdCore::postBuild() // Intialise keyword highlighting for the current simulator's version of LSL LLSyntaxIdLSL::getInstance()->initialize(); + LLSyntaxLua::getInstance()->initialize(); processKeywords(); mCommitCallbackRegistrar.add("FontSize.Set", boost::bind(&LLScriptEdCore::onChangeFontSize, this, _2)); @@ -510,14 +521,31 @@ bool LLScriptEdCore::postBuild() "menu_lsl_font_size.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); getChild("font_btn")->setMenu(context_menu, LLMenuButton::MP_BOTTOM_LEFT, true); + + bool lua_scripts_enabled = have_lua_enabled(LLUUID::null); + mCompileTarget = getChild("compile_target"); + if (LLScrollListItem* luau_item = mCompileTarget->findItemByValue("luau")) + { + luau_item->setEnabled(lua_scripts_enabled); + } + if (LLScrollListItem* lsl_luau_item = mCompileTarget->findItemByValue("lsl-luau")) + { + lsl_luau_item->setEnabled(lua_scripts_enabled); + } + return true; } void LLScriptEdCore::processKeywords() +{ + processKeywords(mEditor->getIsLuauLanguage()); +} + +void LLScriptEdCore::processKeywords(bool luau_language) { LL_DEBUGS("SyntaxLSL") << "Processing keywords" << LL_ENDL; mEditor->clearSegments(); - mEditor->initKeywords(); + mEditor->initKeywords(luau_language); mEditor->loadKeywords(); string_vec_t primary_keywords; @@ -536,6 +564,8 @@ void LLScriptEdCore::processKeywords() secondary_keywords.push_back( wstring_to_utf8str(token->getToken()) ); } } + + mFunctions->removeall(); for (string_vec_t::const_iterator iter = primary_keywords.begin(); iter!= primary_keywords.end(); ++iter) { @@ -691,13 +721,13 @@ bool LLScriptEdCore::writeToFile(const std::string& filename) void LLScriptEdCore::sync() { // Sync with external editor. - if (mLiveFile) + if (mContainer->mLiveFile) { - std::string tmp_file = mLiveFile->filename(); + std::string tmp_file = mContainer->mLiveFile->filename(); llstat s; if (LLFile::stat(tmp_file, &s) == 0) // file exists { - mLiveFile->ignoreNextUpdate(); + mContainer->mLiveFile->ignoreNextUpdate(); writeToFile(tmp_file); } } @@ -1083,15 +1113,21 @@ void LLScriptEdCore::doSave( bool close_after_save ) void LLScriptEdCore::openInExternalEditor() { - delete mLiveFile; // deletes file + //if (mContainer->mLiveFile) + //{ + // // If already open in an external editor, just return + // return; + //} // Generate a suitable filename std::string script_name = mScriptName; - std::string forbidden_chars = "<>:\"\\/|?*"; - for (std::string::iterator c = forbidden_chars.begin(); c != forbidden_chars.end(); c++) - { - script_name.erase(std::remove(script_name.begin(), script_name.end(), *c), script_name.end()); - } + + static const std::set forbidden_chars{ '<', '>', ':', '"', '\\', '/', '|', '?', '*' }; + script_name.erase( + std::remove_if(script_name.begin(), script_name.end(), [](char c) { + return forbidden_chars.contains(c); + }), script_name.end()); + std::string filename = mContainer->getTmpFileName(script_name); // Save the script to a temporary file. @@ -1105,9 +1141,18 @@ void LLScriptEdCore::openInExternalEditor() writeToFile(filename); } + if (mContainer->mLiveFile && mContainer->mLiveFile->filename() != filename) + { // The name may have changed if we changed the type of scipt being edited. + delete mContainer->mLiveFile; + mContainer->mLiveFile = NULL; + } // Start watching file changes. - mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1)); - mLiveFile->addToEventTimer(); + if (!mContainer->mLiveFile) + { + mContainer->mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1)); + mContainer->mLiveFile->addToEventTimer(); + } + mContainer->startWebsocketServer(); // Open it in external editor. { @@ -1376,15 +1421,15 @@ void LLLiveLSLEditor::updateExperiencePanel() mExperienceEnabled->setEnabled(false); mExperienceEnabled->setToolTip(getString("no_experiences")); } - getChild("view_profile")->setVisible(false); + mViewProfileButton->setVisible(false); } else { mExperienceEnabled->setToolTip(getString("experience_enabled")); mExperienceEnabled->setEnabled(getIsModifiable()); - mExperiences->setVisible(true); mExperienceEnabled->set(true); - getChild("view_profile")->setToolTip(getString("show_experience_profile")); + mExperiences->setVisible(true); + mViewProfileButton->setToolTip(getString("show_experience_profile")); buildExperienceList(); } } @@ -1453,7 +1498,7 @@ void LLLiveLSLEditor::buildExperienceList() mExperiences->setEnabled(true); mExperiences->sortByName(true); mExperiences->setCurrentByIndex(mExperiences->getCurrentIndex()); - getChild("view_profile")->setVisible(true); + mViewProfileButton->setVisible(true); } } @@ -1463,8 +1508,6 @@ void LLScriptEdCore::setAssociatedExperience( const LLUUID& experience_id ) mAssociatedExperience = experience_id; } - - void LLLiveLSLEditor::requestExperiences() { if (!getIsModifiable()) @@ -1503,11 +1546,42 @@ void LLLiveLSLEditor::receiveExperienceIds(LLSD result, LLHandlemEditor->getIsLuauLanguage() ? ".luau" : ".lsl"; + + if (script_name.empty()) + { + return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + script_extension; + } + else + { + return std::string(LLFile::tmpdir()) + "sl_script_" + script_name + "_" + script_id_hash_str + script_extension; + } +} + +std::string LLScriptEdContainer::getUniqueHash() const { // Take script inventory item id (within the object inventory) // to consideration so that it's possible to edit multiple scripts @@ -1515,18 +1589,65 @@ std::string LLScriptEdContainer::getTmpFileName(const std::string& script_name) std::string script_id = mObjectUUID.asString() + "_" + mItemUUID.asString(); // Use MD5 sum to make the file name shorter and not exceed maximum path length. - char script_id_hash_str[33]; /* Flawfinder: ignore */ - LLMD5 script_id_hash((const U8 *)script_id.c_str()); + char script_id_hash_str[33]; /* Flawfinder: ignore */ + LLMD5 script_id_hash((const U8*)script_id.c_str()); script_id_hash.hex_digest(script_id_hash_str); - if (script_name.empty()) + return std::string(script_id_hash_str); +} + +std::string LLScriptEdContainer::getErrorLogFileName(const std::string& script_path) +{ + if (script_path.empty()) { - return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl"; + return std::string(); } - else + + return script_path + ".log"; +} + +bool LLScriptEdContainer::logErrorsToFile(const LLSD& compile_errors) +{ + if (!isOpenInExternalEditor()) + { + return false; + } + + std::string script_path = getTmpFileName(mScriptEd->mScriptName); + std::string log_path = getErrorLogFileName(script_path); + + llofstream file(log_path.c_str()); + if (!file.is_open()) + { + LL_WARNS() << "Unable to open error log file: " << log_path << LL_ENDL; + return false; + } + + // Write timestamp + std::string timestamp = LLLogChat::timestamp2LogString(0, true); + file << "// " << timestamp << "\n\n"; + + // Write errors + for (LLSD::array_const_iterator line = compile_errors.beginArray(); + line < compile_errors.endArray(); + line++) + { + std::string error_message = line->asString(); + LLStringUtil::stripNonprintable(error_message); + file << error_message << "\n"; + } + + file.close(); + + // Create a log file handler if we don't already have one, + // this is needed to delete the temporary log file properly + if (!mLiveLogFile && !log_path.empty()) { - return std::string(LLFile::tmpdir()) + "sl_script_" + script_name + "_" + script_id_hash_str + ".lsl"; + // Empty callback since we don't need to react to file changes + mLiveLogFile = new LLLiveLSLFile(log_path, [](const std::string& filename) { return true; }); } + + return true; } bool LLScriptEdContainer::onExternalChange(const std::string& filename) @@ -1556,6 +1677,63 @@ bool LLScriptEdContainer::handleKeyHere(KEY key, MASK mask) return true; } +void LLScriptEdContainer::startWebsocketServer() +{ + if (gSavedSettings.getBOOL("ExternalWebsocketSyncEnable")) + { + // Attempt to find an existing server + LLWebsocketMgr& wsmgr = LLWebsocketMgr::instance(); + LLScriptEditorWSServer::ptr_t server = + std::static_pointer_cast( + wsmgr.findServerByName(LLScriptEditorWSServer::DEFAULT_SERVER_NAME)); + + if (!server) + { // We couldn't find one, so create it + U16 server_port = static_cast(gSavedSettings.getS32("ExternalWebsocketSyncPort")); + bool server_localhost = gSavedSettings.getBOOL("ExternalWebsocketSyncLocal"); + server = std::make_shared(LLScriptEditorWSServer::DEFAULT_SERVER_NAME, server_port, server_localhost); + wsmgr.addServer(server); + } + + bool is_running = server->isRunning(); + if (!is_running) + { // Server isn't running, so start it + is_running = wsmgr.startServer(LLScriptEditorWSServer::DEFAULT_SERVER_NAME); + } + + if (!is_running && !server->isRunning()) + { // Failed to start the server + LL_WARNS() << "Failed to start script editor websocket server" << LL_ENDL; + return; + } + + std::string script_id_hash_str(getUniqueHash()); + server->subscribeScriptEditor(mObjectUUID, mItemUUID, mScriptEd->mScriptName, getHandle(), script_id_hash_str); + mWebSocketServer = server; + } +} + +void LLScriptEdContainer::unsubscribeScript() +{ + auto server = mWebSocketServer.lock(); + if (server) + { + std::string script_id_hash_str(getUniqueHash()); + server->sendUnsubscribeScriptEditor(script_id_hash_str); + server->unsubscribeEditor(script_id_hash_str); + } +} + +void LLScriptEdContainer::sendCompileResults(LLSD& params) +{ + auto server = mWebSocketServer.lock(); + if (server) + { + std::string script_id_hash_str(getUniqueHash()); + server->sendCompileResults(script_id_hash_str, params); + } +} + /// --------------------------------------------------------------------------- /// LLPreviewLSL /// --------------------------------------------------------------------------- @@ -1580,7 +1758,7 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata) self->mScriptEd = new LLScriptEdCore( self, - HELLO_LSL, + std::string(), self->getHandle(), LLPreviewLSL::onLoad, LLPreviewLSL::onSave, @@ -1624,6 +1802,9 @@ bool LLPreviewLSL::postBuild() childSetCommitCallback("desc", LLPreview::onText, this); getChild("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); + mScriptEd->mCompileTarget = getChild("compile_target"); + mScriptEd->mCompileTarget->setCommitCallback([&](LLUICtrl*, const LLSD&) { onCompileTargetChanged(); }); + return LLPreview::postBuild(); } @@ -1649,6 +1830,15 @@ void LLPreviewLSL::callbackLSLCompileSucceeded() LL_INFOS() << "LSL Bytecode saved" << LL_ENDL; mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful")); mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); + + if (isOpenInExternalEditor()) + { + LLSD success_msg; + success_msg.append(LLTrans::getString("CompileSuccessful")); + success_msg.append(LLTrans::getString("SaveComplete")); + logErrorsToFile(success_msg); + } + closeIfNeeded(); } @@ -1668,6 +1858,12 @@ void LLPreviewLSL::callbackLSLCompileFailed(const LLSD& compile_errors) row["columns"][0]["font"] = "OCRA"; mScriptEd->mErrorList->addElement(row); } + + if (isOpenInExternalEditor()) + { + logErrorsToFile(compile_errors); + } + mScriptEd->selectFirstError(); closeIfNeeded(); } @@ -1718,12 +1914,6 @@ void LLPreviewLSL::loadAsset() getChildView("lock")->setVisible( !is_modifiable); mScriptEd->getChildView("Insert...")->setEnabled(is_modifiable); } - else - { - mScriptEd->setScriptText(std::string(HELLO_LSL), true); - mScriptEd->setEnableEditing(true); - mAssetStatus = PREVIEW_ASSET_LOADED; - } } @@ -1781,6 +1971,7 @@ void LLPreviewLSL::finishedLSLUpload(LLUUID itemId, LLSD response) { preview->callbackLSLCompileFailed(response["errors"]); } + preview->sendCompileResults(response); } } @@ -1804,6 +1995,12 @@ bool LLPreviewLSL::failedLSLUpload(LLUUID itemId, LLUUID taskId, LLSD response, LLSD errors; errors.append(LLTrans::getString("UploadFailed") + reason); preview->callbackLSLCompileFailed(errors); + + LLSD message; + message["compiled"] = false; + message["errors"] = errors; + preview->sendCompileResults(message); + return true; } @@ -1839,11 +2036,12 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/) mPendingUploads++; if (!url.empty()) { + std::string compile_target(mScriptEd->mCompileTarget->getValue()); std::string buffer(mScriptEd->mEditor->getText()); LLUUID old_asset_id = inv_item->getAssetUUID().isNull() ? mScriptEd->getAssetID() : inv_item->getAssetUUID(); - LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared(mItemUUID, buffer, + LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared(mItemUUID, compile_target, buffer, [old_asset_id](LLUUID itemId, LLUUID, LLUUID, LLSD response) { LLFileSystem::removeFile(old_asset_id, LLAssetType::AT_LSL_TEXT); LLPreviewLSL::finishedLSLUpload(itemId, response); @@ -1855,6 +2053,11 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/) } } +void LLPreviewLSL::onCompileTargetChanged() +{ + mScriptEd->processKeywords(mScriptEd->mCompileTarget->getValue().asString() == "luau"); +} + // static void LLPreviewLSL::onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status) @@ -1896,6 +2099,12 @@ void LLPreviewLSL::onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType t preview->mScriptEd->setEnableEditing(is_modifiable); preview->mScriptEd->setAssetID(asset_uuid); preview->mAssetStatus = PREVIEW_ASSET_LOADED; + + // Temporary hack to determine if the script is LSL or SLua when loaded from the inventory. + bool is_lua = is_lua_script(std::string(buffer.begin(), buffer.end())); + preview->mScriptEd->mEditor->setLuauLanguage(is_lua); + preview->mScriptEd->mCompileTarget->setValue(is_lua ? "luau" : "lsl-luau"); + preview->mScriptEd->processKeywords(is_lua); } else { @@ -1933,7 +2142,7 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata) self->mScriptEd = new LLScriptEdCore( self, - HELLO_LSL, + std::string(), self->getHandle(), &LLLiveLSLEditor::onLoad, &LLLiveLSLEditor::onSave, @@ -1961,28 +2170,26 @@ LLLiveLSLEditor::LLLiveLSLEditor(const LLSD& key) : bool LLLiveLSLEditor::postBuild() { - childSetCommitCallback("running", LLLiveLSLEditor::onRunningCheckboxClicked, this); - getChildView("running")->setEnabled(false); - - childSetAction("Reset",&LLLiveLSLEditor::onReset,this); - getChildView("Reset")->setEnabled(true); - - mMonoCheckbox = getChild("mono"); - childSetCommitCallback("mono", &LLLiveLSLEditor::onMonoCheckboxClicked, this); - getChildView("mono")->setEnabled(true); - - mScriptEd->mEditor->makePristine(); - mScriptEd->mEditor->setFocus(true); + mResetButton = getChild("Reset"); + mResetButton->setClickedCallback([&](LLUICtrl*, const LLSD&) { onReset(); }); + mRunningCheckbox = getChild("running"); + mRunningCheckbox->setCommitCallback([&](LLUICtrl*, const LLSD&) { onRunningCheckboxClicked(); }); mExperiences = getChild("Experiences..."); - mExperiences->setCommitCallback(boost::bind(&LLLiveLSLEditor::experienceChanged, this)); + mExperiences->setCommitCallback([&](LLUICtrl*, const LLSD&) { experienceChanged(); }); mExperienceEnabled = getChild("enable_xp"); + mExperienceEnabled->setCommitCallback([&](LLUICtrl*, const LLSD&) { onToggleExperience(); }); - childSetCommitCallback("enable_xp", onToggleExperience, this); - childSetCommitCallback("view_profile", onViewProfile, this); + mViewProfileButton = getChild("view_profile"); + mViewProfileButton->setClickedCallback([&](LLUICtrl*, const LLSD&) { onViewProfile(); }); + mScriptEd->mEditor->makePristine(); + mScriptEd->mEditor->setFocus(true); + + mScriptEd->mCompileTarget = getChild("compile_target"); + mScriptEd->mCompileTarget->setCommitCallback([&](LLUICtrl*, const LLSD&) { onCompileTargetChanged(); }); return LLPreview::postBuild(); } @@ -1995,7 +2202,16 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id, LL_DEBUGS() << "LSL Bytecode saved" << LL_ENDL; mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful")); mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); - getChild("running")->set(is_script_running); + + if (isOpenInExternalEditor()) + { + LLSD success_msg; + success_msg.append(LLTrans::getString("CompileSuccessful")); + success_msg.append(LLTrans::getString("SaveComplete")); + logErrorsToFile(success_msg); + } + + mRunningCheckbox->set(is_script_running); mIsSaving = false; closeIfNeeded(); } @@ -2004,6 +2220,7 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id, void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors) { LL_DEBUGS() << "Compile failed!" << LL_ENDL; + for(LLSD::array_const_iterator line = compile_errors.beginArray(); line < compile_errors.endArray(); line++) @@ -2016,6 +2233,12 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors) row["columns"][0]["font"] = "OCRA"; mScriptEd->mErrorList->addElement(row); } + + if (isOpenInExternalEditor()) + { + logErrorsToFile(compile_errors); + } + mScriptEd->selectFirstError(); mIsSaving = false; closeIfNeeded(); @@ -2058,9 +2281,10 @@ void LLLiveLSLEditor::loadAsset() { mItem = new LLViewerInventoryItem(item); // request the text from the object - LLSD* user_data = new LLSD(); - user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID); - gAssetStorage->getInvItemAsset(object->getRegion()->getHost(), + LLSD* user_data = new LLSD(); + user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID); + gAssetStorage->getInvItemAsset( + object->getRegion()->getHost(), gAgent.getID(), gAgent.getSessionID(), item->getPermissions().getOwner(), @@ -2068,8 +2292,8 @@ void LLLiveLSLEditor::loadAsset() item->getUUID(), item->getAssetUUID(), item->getType(), - &LLLiveLSLEditor::onLoadComplete, - (void*)user_data, + LLLiveLSLEditor::onLoadComplete, + user_data, true); LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_GetScriptRunning); @@ -2108,26 +2332,6 @@ void LLLiveLSLEditor::loadAsset() */ } } - else - { - mScriptEd->setScriptText(std::string(HELLO_LSL), true); - mScriptEd->enableSave(false); - LLPermissions perm; - perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, gAgent.getGroupID()); - perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER); - mItem = new LLViewerInventoryItem(mItemUUID, - mObjectUUID, - perm, - LLUUID::null, - LLAssetType::AT_LSL_TEXT, - LLInventoryType::IT_LSL, - DEFAULT_SCRIPT_NAME, - DEFAULT_SCRIPT_DESC, - LLSaleInfo::DEFAULT, - LLInventoryItemFlags::II_FLAGS_NONE, - time_corrected()); - mAssetStatus = PREVIEW_ASSET_LOADED; - } requestExperiences(); } @@ -2203,14 +2407,9 @@ void LLLiveLSLEditor::loadScriptText(const LLUUID &uuid, LLAssetType::EType type } -void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata ) +void LLLiveLSLEditor::onRunningCheckboxClicked() { - LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata; - LLViewerObject* object = gObjectList.findObject( self->mObjectUUID ); - LLCheckBoxCtrl* runningCheckbox = self->getChild("running"); - bool running = runningCheckbox->get(); - //self->mRunningCheckbox->get(); - if( object ) + if (LLViewerObject* object = gObjectList.findObject(mObjectUUID)) { LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_SetScriptRunning); @@ -2218,24 +2417,21 @@ void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata ) msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_Script); - msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectUUID); - msg->addUUIDFast(_PREHASH_ItemID, self->mItemUUID); - msg->addBOOLFast(_PREHASH_Running, running); + msg->addUUIDFast(_PREHASH_ObjectID, mObjectUUID); + msg->addUUIDFast(_PREHASH_ItemID, mItemUUID); + msg->addBOOLFast(_PREHASH_Running, mRunningCheckbox->get()); msg->sendReliable(object->getRegion()->getHost()); } else { - runningCheckbox->set(!running); + mRunningCheckbox->set(!mRunningCheckbox->get()); LLNotificationsUtil::add("CouldNotStartStopScript"); } } -void LLLiveLSLEditor::onReset(void *userdata) +void LLLiveLSLEditor::onReset() { - LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata; - - LLViewerObject* object = gObjectList.findObject( self->mObjectUUID ); - if(object) + if (LLViewerObject* object = gObjectList.findObject(mObjectUUID)) { LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_ScriptReset); @@ -2243,8 +2439,8 @@ void LLLiveLSLEditor::onReset(void *userdata) msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_Script); - msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectUUID); - msg->addUUIDFast(_PREHASH_ItemID, self->mItemUUID); + msg->addUUIDFast(_PREHASH_ObjectID, mObjectUUID); + msg->addUUIDFast(_PREHASH_ItemID, mItemUUID); msg->sendReliable(object->getRegion()->getHost()); } else @@ -2256,34 +2452,33 @@ void LLLiveLSLEditor::onReset(void *userdata) void LLLiveLSLEditor::draw() { LLViewerObject* object = gObjectList.findObject(mObjectUUID); - LLCheckBoxCtrl* runningCheckbox = getChild( "running"); - if(object && mAskedForRunningInfo && mHaveRunningInfo) + if (object && mAskedForRunningInfo && mHaveRunningInfo) { - if(object->permAnyOwner()) + if (object->permAnyOwner()) { - runningCheckbox->setLabel(getString("script_running")); - runningCheckbox->setEnabled(!mIsSaving); + mRunningCheckbox->setLabel(getString("script_running")); + mRunningCheckbox->setEnabled(!mIsSaving); } else { - runningCheckbox->setLabel(getString("public_objects_can_not_run")); - runningCheckbox->setEnabled(false); + mRunningCheckbox->setLabel(getString("public_objects_can_not_run")); + mRunningCheckbox->setEnabled(false); // *FIX: Set it to false so that the ui is correct for // a box that is released to public. It could be // incorrect after a release/claim cycle, but will be // correct after clicking on it. - runningCheckbox->set(false); - mMonoCheckbox->set(false); + mRunningCheckbox->set(false); + mScriptEd->mCompileTarget->clear(); } } - else if(!object) + else if (!object) { // HACK: Display this information in the title bar. // Really ought to put in main window. setTitle(LLTrans::getString("ObjectOutOfRange")); - runningCheckbox->setEnabled(false); - mMonoCheckbox->setEnabled(false); + mRunningCheckbox->setEnabled(false); + mScriptEd->mCompileTarget->setEnabled(false); // object may have fallen out of range. mHaveRunningInfo = false; } @@ -2340,6 +2535,8 @@ void LLLiveLSLEditor::finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAs { preview->callbackLSLCompileFailed(response["errors"]); } + response["is_running"] = isRunning; + preview->sendCompileResults(response); } } @@ -2390,7 +2587,7 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/) mScriptEd->sync(); } - bool isRunning = getChild("running")->get(); + bool is_running = mRunningCheckbox->get(); getWindow()->incBusyCount(); mPendingUploads++; @@ -2398,17 +2595,18 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/) if (!url.empty()) { + std::string compile_target(mScriptEd->mCompileTarget->getValue()); std::string buffer(mScriptEd->mEditor->getText()); LLUUID old_asset_id = mScriptEd->getAssetID(); LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared(mObjectUUID, mItemUUID, - monoChecked() ? LLScriptAssetUpload::MONO : LLScriptAssetUpload::LSL2, - isRunning, mScriptEd->getAssociatedExperience(), buffer, - [isRunning, old_asset_id](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) { - LLFileSystem::removeFile(old_asset_id, LLAssetType::AT_LSL_TEXT); - LLLiveLSLEditor::finishLSLUpload(itemId, taskId, newAssetId, response, isRunning); - }, - nullptr)); // needs failure handling? + compile_target, is_running, mScriptEd->getAssociatedExperience(), buffer, + [is_running, old_asset_id](LLUUID item_id, LLUUID task_id, LLUUID new_asset_id, LLSD response) + { + LLFileSystem::removeFile(old_asset_id, LLAssetType::AT_LSL_TEXT); + LLLiveLSLEditor::finishLSLUpload(item_id, task_id, new_asset_id, response, is_running); + }, + nullptr)); // needs failure handling? LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } @@ -2461,28 +2659,60 @@ void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**) if (LLLiveLSLEditor* instance = LLFloaterReg::findTypedInstance("preview_scriptedit", floater_key)) { instance->mHaveRunningInfo = true; + bool running; msg->getBOOLFast(_PREHASH_Script, _PREHASH_Running, running); - LLCheckBoxCtrl* runningCheckbox = instance->getChild("running"); - runningCheckbox->set(running); - bool mono; - msg->getBOOLFast(_PREHASH_Script, "Mono", mono); - LLCheckBoxCtrl* monoCheckbox = instance->getChild("mono"); - monoCheckbox->setEnabled(instance->getIsModifiable() && have_script_upload_cap(object_id)); - monoCheckbox->set(mono); + instance->mRunningCheckbox->set(running); + + bool mono = false, luau = false, luau_language = false; + msg->getBOOLFast(_PREHASH_Script, _PREHASH_Mono, mono); + msg->getBOOLFast(_PREHASH_Script, _PREHASH_Luau, luau); // Luau compiler is enabled + msg->getBOOLFast(_PREHASH_Script, _PREHASH_LuauLanguage, luau_language); + + std::string compile_target; + if (luau) + { + if (luau_language) + { + compile_target = "luau"; + } + else + { + compile_target = "lsl-luau"; // Luau compiler running in LSL compatibility mode + } + } + else if (mono) + { + compile_target = "mono"; + } + else + { + compile_target = "lsl2"; + } + + instance->mScriptEd->mCompileTarget->setValue(compile_target); + instance->mScriptEd->processKeywords(luau && luau_language); // Use Luau syntax highlighting for Luau scripts + + bool lua_scripts_enabled = have_lua_enabled(object_id); + if (LLScrollListItem* luau_item = instance->mScriptEd->mCompileTarget->findItemByValue("luau")) + { + luau_item->setEnabled(lua_scripts_enabled); + } + if (LLScrollListItem* lsl_luau_item = instance->mScriptEd->mCompileTarget->findItemByValue("lsl-luau")) + { + lsl_luau_item->setEnabled(lua_scripts_enabled); + } + + instance->mScriptEd->mCompileTarget->setEnabled(instance->getIsModifiable() && have_script_upload_cap(object_id)); } } -void LLLiveLSLEditor::onMonoCheckboxClicked(LLUICtrl*, void* userdata) +void LLLiveLSLEditor::onCompileTargetChanged() { - LLLiveLSLEditor* self = static_cast(userdata); - self->mMonoCheckbox->setEnabled(have_script_upload_cap(self->mObjectUUID)); - self->mScriptEd->enableSave(self->getIsModifiable()); -} + mScriptEd->mCompileTarget->setEnabled(have_script_upload_cap(mObjectUUID)); + mScriptEd->enableSave(getIsModifiable()); -bool LLLiveLSLEditor::monoChecked() const -{ - return mMonoCheckbox && mMonoCheckbox->getValue(); + mScriptEd->processKeywords(mScriptEd->mCompileTarget->getValue().asString() == "luau"); } void LLLiveLSLEditor::setAssociatedExperience( LLHandle editor, const LLSD& experience ) diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 0bbe5402079..802d0e12fe6 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -54,6 +54,7 @@ class LLScriptEdContainer; class LLFloaterGotoLine; class LLFloaterExperienceProfile; class LLScriptMovedObserver; +class LLScriptEditorWSServer; class LLLiveLSLFile : public LLLiveFile { @@ -61,12 +62,12 @@ class LLLiveLSLFile : public LLLiveFile typedef boost::function change_callback_t; LLLiveLSLFile(std::string file_path, change_callback_t change_cb); - ~LLLiveLSLFile(); + ~LLLiveLSLFile() override; void ignoreNextUpdate() { mIgnoreNextUpdate = true; } protected: - /*virtual*/ bool loadFile(); + bool loadFile() override; change_callback_t mOnChangeCallback; bool mIgnoreNextUpdate; @@ -82,26 +83,34 @@ class LLScriptEdCore : public LLPanel friend class LLScriptEdContainer; friend class LLFloaterGotoLine; +public: + typedef boost::function script_ed_callback_t; + typedef boost::function save_callback_t; + protected: // Supposed to be invoked only by the container. LLScriptEdCore( LLScriptEdContainer* container, const std::string& sample, const LLHandle& floater_handle, - void (*load_callback)(void* userdata), - void (*save_callback)(void* userdata, bool close_after_save), - void (*search_replace_callback)(void* userdata), + script_ed_callback_t load_callback, + save_callback_t save_callback, + script_ed_callback_t search_replace_callback, void* userdata, bool live, S32 bottom_pad = 0); // pad below bottom row of buttons public: - ~LLScriptEdCore(); + ~LLScriptEdCore() override; void initMenu(); void processKeywords(); + void processKeywords(bool luau_language); + LLScriptEditor* getEditor() const { return mEditor; } + LLKeywords& getKeywords() const { return mEditor->getKeywords(); } + bool isLuauLanguage() const { return mEditor->getIsLuauLanguage(); } - virtual void draw(); - /*virtual*/ bool postBuild(); + void draw() override; + bool postBuild() override; bool canClose(); void setEnableEditing(bool enable); bool canLoadOrSaveToFile( void* userdata ); @@ -134,33 +143,32 @@ class LLScriptEdCore : public LLPanel static bool enableSaveToFileMenu(void* userdata); static bool enableLoadFromFileMenu(void* userdata); - virtual bool hasAccelerators() const { return true; } + bool hasAccelerators() const override { return true; } LLUUID getAssociatedExperience()const; void setAssociatedExperience( const LLUUID& experience_id ); - void setScriptName(const std::string& name){mScriptName = name;}; + void setScriptName(const std::string& name) { mScriptName = name; } - void setItemRemoved(bool script_removed){mScriptRemoved = script_removed;}; + void setItemRemoved(bool script_removed) { mScriptRemoved = script_removed; } void setAssetID( const LLUUID& asset_id){ mAssetID = asset_id; }; LLUUID getAssetID() const { return mAssetID; } - bool isFontSizeChecked(const LLSD &userdata); - void onChangeFontSize(const LLSD &size_name); + bool isFontSizeChecked(const LLSD &userdata); + void onChangeFontSize(const LLSD &size_name); + + bool handleKeyHere(KEY key, MASK mask) override; + void selectAll() { mEditor->selectAll(); } - virtual bool handleKeyHere(KEY key, MASK mask); - void selectAll() { mEditor->selectAll(); } + void enableSave(bool b) { mEnableSave = b; } + bool hasChanged() const; private: void onBtnDynamicHelp(); void onBtnUndoChanges(); - bool hasChanged() const; - void selectFirstError(); - void enableSave(bool b) {mEnableSave = b;} - protected: void deleteBridges(); void setHelpPage(const std::string& help_string); @@ -175,9 +183,9 @@ class LLScriptEdCore : public LLPanel std::string mSampleText; std::string mScriptName; LLScriptEditor* mEditor; - void (*mLoadCallback)(void* userdata); - void (*mSaveCallback)(void* userdata, bool close_after_save); - void (*mSearchReplaceCallback) (void* userdata); + script_ed_callback_t mLoadCallback; + save_callback_t mSaveCallback; + script_ed_callback_t mSearchReplaceCallback; void* mUserdata; LLComboBox *mFunctions; bool mForceClose; @@ -190,19 +198,18 @@ class LLScriptEdCore : public LLPanel S32 mLiveHelpHistorySize; bool mEnableSave; bool mHasScriptData; - LLLiveLSLFile* mLiveFile; LLUUID mAssociatedExperience; bool mScriptRemoved; bool mSaveDialogShown; LLUUID mAssetID; LLTextBox* mLineCol = nullptr; LLButton* mSaveBtn = nullptr; + LLComboBox* mCompileTarget = nullptr; LLScriptEdContainer* mContainer; // parent view -public: + public: boost::signals2::connection mSyntaxIDConnection; - }; class LLScriptEdContainer : public LLPreview @@ -211,15 +218,30 @@ class LLScriptEdContainer : public LLPreview public: LLScriptEdContainer(const LLSD& key); + ~LLScriptEdContainer() override; + + bool handleKeyHere(KEY key, MASK mask) override; - bool handleKeyHere(KEY key, MASK mask); + void startWebsocketServer(); + void unsubscribeScript(); + void sendCompileResults(LLSD&); + + LLScriptEdCore* getScriptEdCore() const { return mScriptEd; } protected: - std::string getTmpFileName(const std::string& script_name); + std::string getTmpFileName(const std::string& script_name) const; + std::string getUniqueHash() const; + std::string getErrorLogFileName(const std::string& script_path); bool onExternalChange(const std::string& filename); virtual void saveIfNeeded(bool sync = true) = 0; + bool logErrorsToFile(const LLSD& compile_errors); + bool isOpenInExternalEditor() const { return mLiveFile != nullptr; } LLScriptEdCore* mScriptEd; + LLLiveLSLFile* mLiveFile = nullptr; + LLLiveLSLFile* mLiveLogFile = nullptr; + + std::weak_ptr mWebSocketServer; }; // Used to view and edit an LSL script from your inventory. @@ -227,7 +249,7 @@ class LLPreviewLSL : public LLScriptEdContainer { public: LLPreviewLSL(const LLSD& key ); - ~LLPreviewLSL(); + ~LLPreviewLSL() override; LLUUID getScriptID() { return mItemUUID; } @@ -236,15 +258,16 @@ class LLPreviewLSL : public LLScriptEdContainer virtual void callbackLSLCompileSucceeded(); virtual void callbackLSLCompileFailed(const LLSD& compile_errors); - /*virtual*/ bool postBuild(); + bool postBuild() override; protected: - virtual void draw(); - virtual bool canClose(); + void draw() override; + bool canClose() override; void closeIfNeeded(); - virtual void loadAsset(); - /*virtual*/ void saveIfNeeded(bool sync = true); + void loadAsset() override; + void saveIfNeeded(bool sync = true) override; + void onCompileTargetChanged(); static void onSearchReplace(void* userdata); static void onLoad(void* userdata); @@ -265,10 +288,8 @@ class LLPreviewLSL : public LLScriptEdContainer S32 mPendingUploads; LLScriptMovedObserver* mItemObserver; - }; - // Used to view and edit an LSL script that is attached to an object. class LLLiveLSLEditor : public LLScriptEdContainer { @@ -276,7 +297,6 @@ class LLLiveLSLEditor : public LLScriptEdContainer public: LLLiveLSLEditor(const LLSD& key); - static void processScriptRunningReply(LLMessageSystem* msg, void**); virtual void callbackLSLCompileSucceeded(const LLUUID& task_id, @@ -284,13 +304,13 @@ class LLLiveLSLEditor : public LLScriptEdContainer bool is_script_running); virtual void callbackLSLCompileFailed(const LLSD& compile_errors); - /*virtual*/ bool postBuild(); + bool postBuild() override; void setIsNew() { mIsNew = true; } static void setAssociatedExperience( LLHandle editor, const LLSD& experience ); - static void onToggleExperience(LLUICtrl *ui, void* userdata); - static void onViewProfile(LLUICtrl *ui, void* userdata); + void onToggleExperience(); + void onViewProfile(); void setExperienceIds(const LLSD& experience_ids); void buildExperienceList(); @@ -300,15 +320,15 @@ class LLLiveLSLEditor : public LLScriptEdContainer void setObjectName(std::string name) { mObjectName = name; } + bool getIsModifiable() const { return mIsModifiable; } // Evaluated on load assert + private: - virtual bool canClose(); + bool canClose() override; void closeIfNeeded(); - virtual void draw(); - - virtual void loadAsset(); - /*virtual*/ void saveIfNeeded(bool sync = true); - bool monoChecked() const; + void draw() override; + void loadAsset() override; + void saveIfNeeded(bool sync = true) override; static void onSearchReplace(void* userdata); static void onLoad(void* userdata); @@ -317,14 +337,14 @@ class LLLiveLSLEditor : public LLScriptEdContainer static void onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status); - static void onRunningCheckboxClicked(LLUICtrl*, void* userdata); - static void onReset(void* userdata); + void onRunningCheckboxClicked(); + void onReset(); void loadScriptText(const LLUUID &uuid, LLAssetType::EType type); static void* createScriptEdPanel(void* userdata); - static void onMonoCheckboxClicked(LLUICtrl*, void* userdata); + void onCompileTargetChanged(); static void finishLSLUpload(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response, bool isRunning); static void receiveExperienceIds(LLSD result, LLHandle parent); @@ -342,19 +362,17 @@ class LLLiveLSLEditor : public LLScriptEdContainer S32 mPendingUploads; bool mIsSaving; + bool mIsModifiable; - bool getIsModifiable() const { return mIsModifiable; } // Evaluated on load assert - - LLCheckBoxCtrl* mMonoCheckbox; - bool mIsModifiable; - - - LLComboBox* mExperiences; - LLCheckBoxCtrl* mExperienceEnabled; - LLSD mExperienceIds; + LLButton* mResetButton { nullptr }; + LLCheckBoxCtrl* mRunningCheckbox { nullptr }; + LLComboBox* mExperiences { nullptr }; + LLCheckBoxCtrl* mExperienceEnabled { nullptr }; + LLButton* mViewProfileButton { nullptr }; + LLSD mExperienceIds; LLHandle mExperienceProfile; - std::string mObjectName; + std::string mObjectName; }; #endif // LL_LLPREVIEWSCRIPT_H diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 3391b7adf78..eb7fe06e7d9 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -211,6 +211,7 @@ void LLReflectionMapManager::update() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("reflection manager update"); llassert(!gCubeSnapshot); // assert a snapshot is not in progress if (LLAppViewer::instance()->logoutRequestSent()) { @@ -222,25 +223,21 @@ void LLReflectionMapManager::update() resume(); } - static LLCachedControl sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1); - static LLCachedControl sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); - static LLCachedControl sReflectionProbeCount(gSavedSettings, "RenderReflectionProbeCount", 256U); - static LLCachedControl sProbeDynamicAllocation(gSavedSettings, "RenderReflectionProbeDynamicAllocation", -1); mResetFade = llmin((F32)(mResetFade + gFrameIntervalSeconds * 2.f), 1.f); { U32 probe_count_temp = mDynamicProbeCount; - if (sProbeDynamicAllocation > -1) + if (mRenderReflectionProbeDynamicAllocation > -1) { - if (sLevel == 0) + if (mRenderReflectionProbeLevel == 0) { mDynamicProbeCount = 1; } - else if (sLevel == 1) + else if (mRenderReflectionProbeLevel == 1) { mDynamicProbeCount = (U32)mProbes.size(); } - else if (sLevel == 2) + else if (mRenderReflectionProbeLevel == 2) { mDynamicProbeCount = llmax((U32)mProbes.size(), 128); } @@ -249,20 +246,20 @@ void LLReflectionMapManager::update() mDynamicProbeCount = 256; } - if (sProbeDynamicAllocation > 1) + if (mRenderReflectionProbeDynamicAllocation > 1) { // Round mDynamicProbeCount to the nearest increment of 16 - mDynamicProbeCount = ((mDynamicProbeCount + sProbeDynamicAllocation / 2) / sProbeDynamicAllocation) * 16; - mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, sReflectionProbeCount); + mDynamicProbeCount = ((mDynamicProbeCount + mRenderReflectionProbeDynamicAllocation / 2) / mRenderReflectionProbeDynamicAllocation) * 16; + mDynamicProbeCount = llclamp(mDynamicProbeCount, 1, mRenderReflectionProbeCount); } else { - mDynamicProbeCount = llclamp(mDynamicProbeCount + sProbeDynamicAllocation, 1, sReflectionProbeCount); + mDynamicProbeCount = llclamp(mDynamicProbeCount + mRenderReflectionProbeDynamicAllocation, 1, mRenderReflectionProbeCount); } } else { - mDynamicProbeCount = sReflectionProbeCount; + mDynamicProbeCount = mRenderReflectionProbeCount; } mDynamicProbeCount = llmin(mDynamicProbeCount, LL_MAX_REFLECTION_PROBE_COUNT); @@ -328,7 +325,7 @@ void LLReflectionMapManager::update() bool did_update = false; - bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; + bool realtime = mRenderReflectionProbeDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME; LLReflectionMap* closestDynamic = nullptr; @@ -457,7 +454,7 @@ void LLReflectionMapManager::update() closestDynamic = probe; } - if (sLevel == 0) + if (mRenderReflectionProbeLevel == 0) { // only update default probe when coverage is set to none llassert(probe == mDefaultProbe); @@ -489,12 +486,12 @@ void LLReflectionMapManager::update() static LLCachedControl sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f); if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod) { - if (sLevel == 0) + if (mRenderReflectionProbeLevel == 0) { // when probes are disabled don't update the default probe more often than the prescribed update period oldestProbe = nullptr; } } - else if (sLevel > 0) + else if (mRenderReflectionProbeLevel > 0) { // when probes are enabled don't update the default probe less often than the prescribed update period oldestProbe = mDefaultProbe; } @@ -520,6 +517,14 @@ void LLReflectionMapManager::update() } } +void LLReflectionMapManager::refreshSettings() +{ + mRenderReflectionProbeDetail = gSavedSettings.getS32("RenderReflectionProbeDetail"); + mRenderReflectionProbeLevel = gSavedSettings.getS32("RenderReflectionProbeLevel"); + mRenderReflectionProbeCount = gSavedSettings.getU32("RenderReflectionProbeCount"); + mRenderReflectionProbeDynamicAllocation = gSavedSettings.getS32("RenderReflectionProbeDynamicAllocation"); +} + LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group) { if (gGLManager.mGLVersion < 4.05f || !LLPipeline::sReflectionProbesEnabled) @@ -756,6 +761,8 @@ void LLReflectionMapManager::doProbeUpdate() // In effect this simulates single-bounce lighting. void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("probe update"); // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; @@ -782,7 +789,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } else { - llassert(gSavedSettings.getS32("RenderReflectionProbeLevel") > 0); // should never update a probe that's not the default probe if reflection coverage is none + llassert(mRenderReflectionProbeLevel > 0); // should never update a probe that's not the default probe if reflection coverage is none probe->update(mRenderTarget.getWidth(), face); } @@ -1071,6 +1078,7 @@ void LLReflectionMapManager::updateUniforms() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("rmmu - uniforms") mReflectionMaps.resize(mReflectionProbeCount); diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 0719c281345..5daed7d1cf1 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -110,6 +110,8 @@ class alignas(16) LLReflectionMapManager // maintain reflection probes void update(); + void refreshSettings(); + // add a probe for the given spatial group LLReflectionMap* addProbe(LLSpatialGroup* group = nullptr); @@ -248,6 +250,12 @@ class alignas(16) LLReflectionMapManager U32 mDynamicProbeCount; + // cached settings from gSavedSettings + S32 mRenderReflectionProbeDetail = -1; + S32 mRenderReflectionProbeLevel = 3; + U32 mRenderReflectionProbeCount = 256U; + S32 mRenderReflectionProbeDynamicAllocation = -1; + // resolution of reflection probes U32 mProbeResolution = 128; diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 59cf3ac02b4..2a9dd73936c 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -45,7 +45,8 @@ LLScriptEditor::Params::Params() LLScriptEditor::LLScriptEditor(const Params& p) : LLTextEditor(p) , mShowLineNumbers(p.show_line_numbers), - mUseDefaultFontSize(p.default_font_size) + mUseDefaultFontSize(p.default_font_size), + mLuauLanguage(false) { if (mShowLineNumbers) { @@ -141,20 +142,24 @@ void LLScriptEditor::drawLineNumbers() } } -void LLScriptEditor::initKeywords() +void LLScriptEditor::initKeywords(bool luau_language) { - mKeywords.initialize(LLSyntaxIdLSL::getInstance()->getKeywordsXML()); + mKeywordsLua.initialize(LLSyntaxLua::getInstance()->getKeywordsXML(), true); + mKeywordsLSL.initialize(LLSyntaxIdLSL::getInstance()->getKeywordsXML(), false); + + mLuauLanguage = luau_language; + } void LLScriptEditor::loadKeywords() { LL_PROFILE_ZONE_SCOPED; - mKeywords.processTokens(); + getKeywords().processTokens(); LLStyleConstSP style = new LLStyle(LLStyle::Params().font(getScriptFont()).color(mDefaultColor.get())); segment_vec_t segment_list; - mKeywords.findSegments(&segment_list, getWText(), *this, style); + getKeywords().findSegments(&segment_list, getWText(), *this, style); mSegments.clear(); segment_set_t::iterator insert_it = mSegments.begin(); @@ -166,7 +171,7 @@ void LLScriptEditor::loadKeywords() void LLScriptEditor::updateSegments() { - if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly) + if (mReflowIndex < S32_MAX && getKeywords().isLoaded() && mParseOnTheFly) { LL_PROFILE_ZONE_SCOPED; @@ -174,7 +179,7 @@ void LLScriptEditor::updateSegments() // HACK: No non-ascii keywords for now segment_vec_t segment_list; - mKeywords.findSegments(&segment_list, getWText(), *this, style); + getKeywords().findSegments(&segment_list, getWText(), *this, style); clearSegments(); for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it) @@ -194,6 +199,21 @@ void LLScriptEditor::clearSegments() } } +LLKeywords::keyword_iterator_t LLScriptEditor::keywordsBegin() +{ + return getKeywords().begin(); +} + +LLKeywords::keyword_iterator_t LLScriptEditor::keywordsEnd() +{ + return getKeywords().end(); +} + +LLKeywords& LLScriptEditor::getKeywords() +{ + return mLuauLanguage ? mKeywordsLua : mKeywordsLSL; +} + // Most of this is shamelessly copied from LLTextBase void LLScriptEditor::drawSelectionBackground() { @@ -218,7 +238,6 @@ void LLScriptEditor::drawSelectionBackground() ++rect_it) { LLRect selection_rect = *rect_it; - selection_rect = *rect_it; selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom); gl_rect_2d(selection_rect, selection_color); } diff --git a/indra/newview/llscripteditor.h b/indra/newview/llscripteditor.h index 1632ebe8341..2d98110f75a 100644 --- a/indra/newview/llscripteditor.h +++ b/indra/newview/llscripteditor.h @@ -41,17 +41,20 @@ class LLScriptEditor : public LLTextEditor Params(); }; - virtual ~LLScriptEditor() {}; + ~LLScriptEditor() override {}; // LLView override - virtual void draw(); - bool postBuild(); + void draw() override; + bool postBuild() override; - void initKeywords(); + void initKeywords(bool luau_language = false); void loadKeywords(); - /* virtual */ void clearSegments(); - LLKeywords::keyword_iterator_t keywordsBegin() { return mKeywords.begin(); } - LLKeywords::keyword_iterator_t keywordsEnd() { return mKeywords.end(); } + void clearSegments(); + LLKeywords::keyword_iterator_t keywordsBegin(); + LLKeywords::keyword_iterator_t keywordsEnd(); + LLKeywords& getKeywords(); + bool getIsLuauLanguage() { return mLuauLanguage; } + void setLuauLanguage(bool luau_language) { mLuauLanguage = luau_language; } static std::string getScriptFontSize(); LLFontGL* getScriptFont(); @@ -63,12 +66,13 @@ class LLScriptEditor : public LLTextEditor private: void drawLineNumbers(); - /* virtual */ void updateSegments(); - /* virtual */ void drawSelectionBackground(); - void loadKeywords(const std::string& filename_keywords, - const std::string& filename_colors); + void updateSegments() override; + void drawSelectionBackground() override; + + LLKeywords mKeywordsLua; + LLKeywords mKeywordsLSL; + bool mLuauLanguage; - LLKeywords mKeywords; bool mShowLineNumbers; bool mUseDefaultFontSize; }; diff --git a/indra/newview/llscripteditorws.cpp b/indra/newview/llscripteditorws.cpp new file mode 100644 index 00000000000..814157e86c2 --- /dev/null +++ b/indra/newview/llscripteditorws.cpp @@ -0,0 +1,830 @@ +/** + * @file llscripteditorws.cpp + * @brief JSON-RPC 2.0 WebSocket server implementation for external script editor integration + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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 "llviewerprecompiledheaders.h" +#include "llscripteditorws.h" +#include "llpreviewscript.h" +#include "llappviewer.h" +#include "lltrans.h" +#include "lldate.h" +#include "llerror.h" +#include "lluuid.h" +#include "llversioninfo.h" +#include "llagent.h" +#include "llregex.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "llchat.h" + +//======================================================================== +LLScriptEditorWSServer::LLScriptEditorWSServer(const std::string& name, U16 port, bool local_only) + : LLJSONRPCServer(name, port, local_only) +{ + LL_INFOS("ScriptEditorWS") << "Created JSON-RPC script editor server: " << name + << " on port " << port << LL_ENDL; +} + +LLScriptEditorWSServer::ptr_t LLScriptEditorWSServer::getServer() +{ + if (!LLWebsocketMgr::instanceExists()) + { + return nullptr; + } + LLWebsocketMgr& wsmgr = LLWebsocketMgr::instance(); + return std::static_pointer_cast( + wsmgr.findServerByName(LLScriptEditorWSServer::DEFAULT_SERVER_NAME)); +} + + +LLWebsocketMgr::WSConnection::ptr_t LLScriptEditorWSServer::connectionFactory(LLWebsocketMgr::WSServer::ptr_t server, + LLWebsocketMgr::connection_h handle) +{ + auto connection = std::make_shared(server, handle); + mActiveConnections[connection->getConnectionID()] = connection; + + // Call setupConnectionMethods to register any global methods + setupConnectionMethods(connection); + + return connection; +} + +void LLScriptEditorWSServer::onStarted() +{ + LLSyntaxIdLSL& syntax_id_mgr = LLSyntaxIdLSL::instance(); + wptr_t that(std::static_pointer_cast(shared_from_this())); + + mLastSyntaxId = syntax_id_mgr.getSyntaxID(); + mLanguageChangeSignal = syntax_id_mgr.addSyntaxIDCallback( + [that]() + { + auto server = that.lock(); + if (server && server->isRunning()) + { + server->broadcastLanguageChange(); + } + }); +} + +void LLScriptEditorWSServer::onStopped() +{ + mLanguageChangeSignal.disconnect(); + mLastSyntaxId.setNull(); +} + +void LLScriptEditorWSServer::onConnectionOpened(const LLWebsocketMgr::WSConnection::ptr_t& connection) +{ + // Call parent class to handle JSON-RPC setup and standard methods + LLJSONRPCServer::onConnectionOpened(connection); + + LL_INFOS("ScriptEditorWS") << "New script editor client connected via JSON-RPC" << LL_ENDL; + +} + +void LLScriptEditorWSServer::onConnectionClosed(const LLWebsocketMgr::WSConnection::ptr_t& connection) +{ + // Call parent class to handle JSON-RPC cleanup + LLJSONRPCServer::onConnectionClosed(connection); + + LL_INFOS("ScriptEditorWS") << "Script editor client disconnected" << LL_ENDL; + + // Remove from active connections + auto script_connection = std::dynamic_pointer_cast(connection); + if (script_connection) + { + U32 connection_id = script_connection->getConnectionID(); + unsubscribeConnection(connection_id); + mActiveConnections.erase(connection_id); + + LL_DEBUGS("ScriptEditorWS") << "Removed connection from active connections. Total: " + << mActiveConnections.size() << LL_ENDL; + // TODO: When connections reach 0, stop the server after a timeout. + } +} + +bool LLScriptEditorWSServer::subscribeScriptEditor(const LLUUID& object_id, const LLUUID& item_id, std::string_view script_name, + const LLHandle& editor_handle, const std::string& script_id) +{ + if (!editor_handle.isDead()) + { + auto it = mSubscriptions.find(script_id); + if (it == mSubscriptions.end()) + { // Don't re-add if already subscribed + mSubscriptions.emplace(script_id, + LLScriptEditorWSServer::EditorSubscription(object_id, item_id, script_name, editor_handle)); + return false; + } + else + { // Update existing subscription with new editor handle + it->second.mEditorHandle = editor_handle; + } + return true; + } + return false; +} + +void LLScriptEditorWSServer::unsubscribeEditor(const std::string &script_id) +{ + auto it = mSubscriptions.find(script_id); + if (it != mSubscriptions.end()) + { + S32 connection_id = it->second.mConnectionID; + auto connection = it->second.mConnection.lock(); + mSubscriptions.erase(it); + ptrdiff_t count = std::count_if(mSubscriptions.begin(), mSubscriptions.end(), [connection_id](const auto& pair) { + return pair.second.mConnectionID == connection_id; + }); + if (connection && !count) + { // We have removed the last subscription, close the connection + LL_DEBUGS("ScriptEditorWS") << "Closing connection ID " << connection_id << + " as last subscription was removed" << LL_ENDL; + connection->sendDisconnect(LLScriptEditorWSConnection::REASON_EDITOR_CLOSED, "Editor closed"); + } + + } +} + +void LLScriptEditorWSServer::unsubscribeConnection(U32 connection_id) +{ + for (auto it = mSubscriptions.begin(); it != mSubscriptions.end(); ) + { + if (it->second.mConnectionID == connection_id) + { + LL_DEBUGS("ScriptEditorWS") << "Unsubscribing script " << it->first + << " from connection ID " << connection_id << LL_ENDL; + it = mSubscriptions.erase(it); + } + else + { + ++it; + } + } +} + +LLScriptEditorWSServer::SubscriptionError_t LLScriptEditorWSServer::updateScriptSubscription(const std::string &script_id, U32 connection_id) +{ + auto it = mSubscriptions.find(script_id); + if (it != mSubscriptions.end()) + { + if (it->second.mEditorHandle.isDead()) + { + unsubscribeEditor(script_id); + return SUBSCRIPTION_INVALID_EDITOR; + } + + auto con_it = mActiveConnections.find(connection_id); + if (con_it == mActiveConnections.end()) + { + return SUBSCRIPTION_INTERNAL_ERROR; + } + + if ((it->second.mConnectionID != 0) && !it->second.mConnection.expired() + && it->second.mConnection.lock()->isConnected()) + { + LL_WARNS("ScriptEditorWS") << "Script " << script_id << " is already subscribed on connection ID " << it->second.mConnectionID + << ", cannot subscribe again on connection ID " << connection_id << LL_ENDL; + // In the future we may want to support multiple connections per script. + // That would imply it was open in multiple editors. + return SUBSCRIPTION_ALREADY_SUBSCRIBED; + } + + it->second.mConnectionID = connection_id; + it->second.mConnection = con_it->second; + return SUBSCRIPTION_SUCCESS; + } + return SUBSCRIPTION_INVALID_SUBSCRIPTION; +} + + +LLHandle LLScriptEditorWSServer::findEditorForScript(const std::string& script_id) const +{ + auto it = mSubscriptions.find(script_id); + if (it != mSubscriptions.end()) + { + return it->second.mEditorHandle; + } + return LLHandle(); +} + +std::set LLScriptEditorWSServer::getActiveScripts() const +{ + std::set active_scripts; + for (const auto& [script_id, subinfo] : mSubscriptions) + { + if (!subinfo.mEditorHandle.isDead()) + { + active_scripts.insert(script_id); + } + } + return active_scripts; +} + +void LLScriptEditorWSServer::setupConnectionMethods(LLJSONRPCConnection::ptr_t connection) +{ + // Call parent class to register global JSON-RPC methods + LLJSONRPCServer::setupConnectionMethods(connection); + + // Cast to our specific connection type to access script editor functionality + auto script_connection = std::dynamic_pointer_cast(connection); + if (script_connection) + { + LL_DEBUGS("ScriptEditorWS") << "Setting up script editor connection methods" << LL_ENDL; + wptr_t that(std::static_pointer_cast(shared_from_this())); + + U32 connection_id = script_connection->getConnectionID(); + + script_connection->registerMethod("language.syntax.id", + [that](const std::string&, const LLSD&, const LLSD&) -> LLSD + { + auto server = that.lock(); + if (server) + { + return server->handleLanguageIdRequest(); + } + return LLSD(); + }); + script_connection->registerMethod("language.syntax", + [that](const std::string&, const LLSD&, const LLSD& params) + { + auto server = that.lock(); + if (server) + { + return server->handleSyntaxRequest(params); + } + return LLSD(); + }); + script_connection->registerMethod("script.subscribe", + [that, connection_id](const std::string&, const LLSD&, const LLSD& params) -> LLSD + { + auto server = that.lock(); + if (server) + { + return server->handleScriptSubscribe(connection_id, params); + } + return LLSD(); + }); + script_connection->registerMethod("script.unsubscribe", [](const std::string&, const LLSD&, const LLSD& params) -> LLSD + { // this is a notification, no response expected + return LLSD(); + }); + // script_connection->registerMethod("language.syntax", ) + } +} + +void LLScriptEditorWSServer::broadcastLanguageChange() +{ + LLUUID syntax_id = LLSyntaxIdLSL::instance().getSyntaxID(); + + if (syntax_id != mLastSyntaxId) + { + mLastSyntaxId = syntax_id; + LLSD params; + params["id"] = syntax_id; + + if (isRunning()) + { + broadcastNotification("language.syntax.change", params); + } + } +} + +LLSD LLScriptEditorWSServer::handleLanguageIdRequest() const +{ + LLSD response; + + response["id"] = mLastSyntaxId; + return response; +} + +LLSD LLScriptEditorWSServer::handleSyntaxRequest(const LLSD& params) const +{ + LLSD response(LLSD::emptyMap()); + std::string category = params["kind"].asString(); + + if (category.empty()) + { + response["error"] = "No syntax category specified"; + response["success"] = false; + return response; + } + + response["id"] = mLastSyntaxId; + if (category == "defs.lua") + { + response["defs"] = LLSyntaxLua::instance().getTypesXML(); + response["success"] = response["defs"].isDefined(); + } + else if (category == "defs.lsl") + { + response["defs"] = LLSyntaxIdLSL::instance().getKeywordsXML(); + response["success"] = response["defs"].isDefined(); + } + else + { + response["error"] = "Unknown syntax category requested"; + response["success"] = false; + } + return response; +} + +LLSD LLScriptEditorWSServer::handleScriptSubscribe(U32 connection_id, const LLSD& params) +{ + LLSD response(LLSD::emptyMap()); + + std::string script_id = params["script_id"].asString(); + std::string script_name = params["script_name"].asString(); + std::string language = params["script_language"].asString(); + + SubscriptionError_t result = updateScriptSubscription(script_id, connection_id); + + response["script_id"] = script_id; + response["success"] = (result == SUBSCRIPTION_SUCCESS); + response["status"] = result; + + LL_WARNS_IF(result != SUBSCRIPTION_SUCCESS, "ScriptEditorWS") + << "Script connect request for script " << script_id << " failed with status " << result << LL_ENDL; + switch (result) + { + case SUBSCRIPTION_SUCCESS: + response["message"] = "OK"; + break; + case SUBSCRIPTION_INVALID_EDITOR: + response["message"] = "Invalid editor handle"; + break; + case SUBSCRIPTION_INVALID_SUBSCRIPTION: + response["message"] = "No subscription found for script"; + break; + case SUBSCRIPTION_ALREADY_SUBSCRIBED: + response["message"] = "Script already subscribed"; + break; + case SUBSCRIPTION_INTERNAL_ERROR: + response["message"] = "Internal server error"; + break; + } + + if (result == SUBSCRIPTION_SUCCESS) + { + auto it = mSubscriptions.find(script_id); + if (it != mSubscriptions.end()) + { + LLViewerObject* object = gObjectList.findObject((*it).second.mObjectID); + response["object_id"] = (*it).second.mObjectID; + //response["object_name"] = object ? object->getName() : "Unknown"; + response["item_id"] = (*it).second.mItemID; + } + } + + return response; +} + +LLSD LLScriptEditorWSServer::handleScriptUnsubscribe(U32 connection_id, const LLSD& params) +{ + std::string script_id = params["script_id"].asString(); + + auto it = mSubscriptions.find(script_id); + if (it != mSubscriptions.end() && (it->second.mConnectionID == connection_id)) + { + unsubscribeEditor(script_id); + } + return LLSD(); +} + +void LLScriptEditorWSServer::notifyScript(const std::string& script_id, const std::string &method, const LLSD& message) const +{ + auto it = mSubscriptions.find(script_id); + if (it != mSubscriptions.end()) + { + auto connection = it->second.mConnection.lock(); + if (connection) + { + connection->notify(method, message); + } + } +} + + +void LLScriptEditorWSServer::sendUnsubscribeScriptEditor(const std::string& script_id) +{ + LLSD params; + params["script_id"] = script_id; + + notifyScript(script_id, "script.unsubscribe", params); +} + +void LLScriptEditorWSServer::sendCompileResults(const std::string &script_id, const LLSD &results) const +{ + LLHandle editor_handle = findEditorForScript(script_id); + if (editor_handle.isDead()) + { + return; + } + LLScriptEdContainer* editor = dynamic_cast(editor_handle.get()); + if (!editor) + { + return; + } + LLScriptEdCore* core = editor->getScriptEdCore(); + bool is_lua = core && (core->isLuauLanguage()); + + LLSD params; + params["script_id"] = script_id; + params["success"] = results["compiled"].asBoolean(); + params["running"] = results["is_running"].asBoolean(); + if (results.has("errors")) + { + params["errors"] = LLSD::emptyArray(); + + if (is_lua) + { // lua errors: ":line: message", line is 1-based + const static boost::regex lua_err_regex(R"(^[^:]*:(\d+): (.+)$)"); + + for (const auto& err : llsd::inArray(results["errors"])) + { + boost::smatch match; + LLSD err_entry; + + err_entry["column"] = 0; // TODO: Lua compiler does not provide column info + err_entry["level"] = "ERROR"; + + if (boost::regex_match(err.asString(), match, lua_err_regex)) + { + S32 line_number = std::stoi(match[1].str()); + std::string message = match[2].str(); + + err_entry["row"] = line_number; + err_entry["message"] = message; + } + else + { + err_entry["row"] = 0; + err_entry["message"] = err.asString(); + } + params["errors"].append(err_entry); + } + } + else + { // lsl errors: "(line, column) : SEVERITY : message", line and column are 0-based + static const boost::regex lsl_err_regex(R"(\((\d+), (\d+)\) : ([^:]+) : (.+))"); + + for (const auto& err : llsd::inArray(results["errors"])) + { + boost::smatch match; + LLSD err_entry; + + if (boost::regex_match(err.asString(), match, lsl_err_regex)) + { + S32 line_number = std::stoi(match[1].str()); + S32 col_number = std::stoi(match[2].str()); + std::string severity = match[3].str(); + std::string message = match[4].str(); + + err_entry["row"] = line_number + 1; + err_entry["column"] = col_number + 1; + err_entry["level"] = severity; + err_entry["message"] = message; + err_entry["format"] = "lsl"; + } + else + { + err_entry["row"] = 0; + err_entry["column"] = 0; + err_entry["level"] = "ERROR"; + err_entry["message"] = err.asString(); + err_entry["format"] = "lsl"; + } + params["errors"].append(err_entry); + } + } + } + + notifyScript(script_id, "script.compiled", params); +} + +void LLScriptEditorWSServer::forwardChatToIDE(const LLChat& chat_msg) const +{ + auto it = std::find_if(mSubscriptions.begin(), mSubscriptions.end(), + [&chat_msg](const auto& pair) { return (pair.second.mObjectID == chat_msg.mFromID); }); + + if (it == mSubscriptions.end()) + { // Not a script we are tracking + return; + } + + bool is_error = false; + std::string error_message; + std::string object_name; + std::string script_name; + S32 line_number = 0; + // We have at least one script from this object, we will forward the message to the IDE + // but first we need to see if it is a runtime error + std::vector lines = LLStringUtil::getTokens(chat_msg.mText, "\n"); + // If this is a runtime error, the first line will look like: " [script: