summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRider Linden <rider@lindenlab.com>2026-05-05 15:51:49 -0700
committerGitHub <noreply@github.com>2026-05-05 15:51:49 -0700
commitbbce410f87643d8bdd2870aa74fe208a74766dfb (patch)
tree13e05998311f4124bbfe19e363d16a18e2613591
parent65b9b2cb5cde2c344da51a7b677c1b99591d8ad3 (diff)
parenta453db20bb49193806fb0cafeb4d50db4a16abe4 (diff)
Merge pull request #5739 from secondlife/rider/defs_cap
Get pregenerated config files from the simulator cap and make them available through the websocket.
-rw-r--r--autobuild.xml88
-rw-r--r--doc/external-editor-json-rpc.md234
-rw-r--r--indra/cmake/LSLDefinitions.cmake4
-rw-r--r--indra/llmessage/llcorehttputil.cpp33
-rw-r--r--indra/llmessage/llcorehttputil.h1
-rw-r--r--indra/newview/CMakeLists.txt1
-rw-r--r--indra/newview/app_settings/types_lua_default.xml5262
-rw-r--r--indra/newview/llpreviewscript.cpp5
-rw-r--r--indra/newview/llscripteditor.cpp4
-rw-r--r--indra/newview/llscripteditorws.cpp99
-rw-r--r--indra/newview/llscripteditorws.h2
-rw-r--r--indra/newview/llsyntaxid.cpp535
-rw-r--r--indra/newview/llsyntaxid.h142
-rw-r--r--indra/newview/llviewerregion.cpp1
-rwxr-xr-xindra/newview/viewer_manifest.py12
15 files changed, 795 insertions, 5628 deletions
diff --git a/autobuild.xml b/autobuild.xml
index feca45d6d8..3f07900e58 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1326,18 +1326,6 @@
</map>
<key>lsl_definitions</key>
<map>
- <key>canonical_repo</key>
- <string>https://github.com/secondlife/lsl-definitions</string>
- <key>copyright</key>
- <string>Copyright (c) 2026, Linden Lab</string>
- <key>description</key>
- <string>LSL definitions</string>
- <key>license</key>
- <string>MIT</string>
- <key>license_file</key>
- <string>LICENSES/lsl_definitions.txt</string>
- <key>name</key>
- <string>lsl_definitions</string>
<key>platforms</key>
<map>
<key>common</key>
@@ -1345,28 +1333,40 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>6e4e3b86f5daf6dc2e7d7b2b59deaaad293b7232</string>
+ <string>9e8a23b240897ca2e98f6700fae3bec46ad0d0f2</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/lsl-definitions/releases/download/v0.4.1/lsl_definitions-0.4.1-common-22871771849.tar.zst</string>
+ <string>https://github.com/secondlife/lsl-definitions/releases/download/v0.6.3/lsl_definitions-0.6.3-common-25336758775.tar.zst</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
- <key>source_type</key>
- <string>git</string>
+ <key>license</key>
+ <string>MIT</string>
+ <key>license_file</key>
+ <string>LICENSES/lsl_definitions.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2026, Linden Lab</string>
+ <key>version</key>
+ <string>0.6.3</string>
<key>use_scm_version</key>
<boolean>true</boolean>
+ <key>name</key>
+ <string>lsl_definitions</string>
<key>vcs_branch</key>
<string>refs/tags/v0.4.1</string>
<key>vcs_revision</key>
<string>03006fb488cba2bae502e9baed051bfc8d00144d</string>
<key>vcs_url</key>
<string>git://github.com/secondlife/lsl-definitions.git</string>
- <key>version</key>
- <string>0.4.1</string>
+ <key>canonical_repo</key>
+ <string>https://github.com/secondlife/lsl-definitions</string>
+ <key>description</key>
+ <string>LSL definitions</string>
+ <key>source_type</key>
+ <string>git</string>
</map>
<key>meshoptimizer</key>
<map>
@@ -2473,16 +2473,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
</map>
<key>webrtc</key>
<map>
- <key>canonical_repo</key>
- <string>https://github.com/secondlife/3p-webrtc-build</string>
- <key>copyright</key>
- <string>Copyright (c) 2011, The WebRTC project authors. All rights reserved.</string>
- <key>license</key>
- <string>MIT</string>
- <key>license_file</key>
- <string>LICENSES/webrtc-license.txt</string>
- <key>name</key>
- <string>webrtc</string>
<key>platforms</key>
<map>
<key>darwin64</key>
@@ -2528,14 +2518,24 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>windows64</string>
</map>
</map>
+ <key>license</key>
+ <string>MIT</string>
+ <key>license_file</key>
+ <string>LICENSES/webrtc-license.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2011, The WebRTC project authors. All rights reserved.</string>
+ <key>version</key>
+ <string>m137.7151.04.23.22004231636</string>
+ <key>name</key>
+ <string>webrtc</string>
<key>vcs_branch</key>
<string>secondlife</string>
<key>vcs_revision</key>
<string>d3f62d32bac8694d3c7423c731ae30c113bf6a11</string>
<key>vcs_url</key>
<string>https://github.com/secondlife/3p-webrtc-build</string>
- <key>version</key>
- <string>m137.7151.04.23.22004231636</string>
+ <key>canonical_repo</key>
+ <string>https://github.com/secondlife/3p-webrtc-build</string>
</map>
<key>xxhash</key>
<map>
@@ -2813,18 +2813,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
</map>
<key>websocketpp</key>
<map>
- <key>canonical_repo</key>
- <string>https://github.com/secondlife/3p-websocketpp</string>
- <key>copyright</key>
- <string>Copyright (c) 2014, Peter Thorson</string>
- <key>description</key>
- <string>WebSocket++ is a C++ header only library for interacting with WebSocket servers and clients.</string>
- <key>license</key>
- <string>websocketpp</string>
- <key>license_file</key>
- <string>LICENSES/websocketpp.txt</string>
- <key>name</key>
- <string>websocketpp</string>
<key>platforms</key>
<map>
<key>common</key>
@@ -2842,14 +2830,26 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>common</string>
</map>
</map>
+ <key>license</key>
+ <string>websocketpp</string>
+ <key>license_file</key>
+ <string>LICENSES/websocketpp.txt</string>
+ <key>copyright</key>
+ <string>Copyright (c) 2014, Peter Thorson</string>
+ <key>version</key>
+ <string>0.8.2.24525603568</string>
+ <key>name</key>
+ <string>websocketpp</string>
<key>vcs_branch</key>
<string>refs/tags/v0.8.2</string>
<key>vcs_revision</key>
<string>bdcf1453101976fc4dc26a62c87bc98c12e9c6dc</string>
<key>vcs_url</key>
<string>git://github.com/secondlife/3p-websocketpp.git</string>
- <key>version</key>
- <string>0.8.2.24525603568</string>
+ <key>canonical_repo</key>
+ <string>https://github.com/secondlife/3p-websocketpp</string>
+ <key>description</key>
+ <string>WebSocket++ is a C++ header only library for interacting with WebSocket servers and clients.</string>
</map>
</map>
<key>package_description</key>
diff --git a/doc/external-editor-json-rpc.md b/doc/external-editor-json-rpc.md
index b8c7fa69e3..202f1e5b29 100644
--- a/doc/external-editor-json-rpc.md
+++ b/doc/external-editor-json-rpc.md
@@ -1,6 +1,6 @@
# Viewer to External Editor JSON-RPC<br>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.
+This document describes all the message interfaces defined for WebSocket communication between the Second Life viewer and an external editor such as a VSCode extension.
## Table of Contents
@@ -15,10 +15,13 @@ This document describes all the message interfaces defined in for WebSocket comm
- [SyntaxChange](#syntaxchange)
- [Language Syntax ID Request](#language-syntax-id-request)
- [Language Syntax Request](#language-syntax-request)
+ - [Language Syntax Cache List](#language-syntax-cache-list)
+ - [Language Syntax Cache Get](#language-syntax-cache-get)
- [Script Subscription Interfaces](#script-subscription-interfaces)
- [ScriptSubscribe](#scriptsubscribe)
- [ScriptSubscribeResponse](#scriptsubscriberesponse)
- [ScriptUnsubscribe](#scriptunsubscribe)
+ - [ScriptList](#scriptlist)
- [Compilation Interfaces](#compilation-interfaces)
- [CompilationError](#compilationerror)
- [CompilationResult](#compilationresult)
@@ -33,7 +36,7 @@ This document describes all the message interfaces defined in for WebSocket comm
1. **Connection Establishment:**
- - Viewer sends `session.handshake` notification with `SessionHandshake` data
+ - Viewer sends `session.handshake` call with `SessionHandshake` data
- Extension responds with `SessionHandshakeResponse`
- Viewer confirms with `session.ok` notification
@@ -41,7 +44,7 @@ This document describes all the message interfaces defined in for WebSocket comm
- 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
+ - Viewer responds with a `LanguageInfo` object containing the requested definitions
3. **Script Subscription Management:**
@@ -65,17 +68,23 @@ This document describes all the message interfaces defined in for WebSocket comm
| Method | Direction | Type | Interface/Parameters |
| ------------------------------- | ------------------ | ------------ | -------------------------- |
-| `session.handshake` | Viewer → Extension | Notification | `SessionHandshake` |
+| `session.handshake` | Viewer → Extension | Call | `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` |
+| `script.list` | Extension → Viewer | Call | _(no parameters)_ |
+| `script.list` (response) | Viewer → Extension | Response | `ScriptList` |
| `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.cache` | Extension → Viewer | Call | _(no parameters)_ |
+| `language.syntax.cache` (response) | Viewer → Extension | Response | `SyntaxCacheList` |
+| `language.syntax.get` | Extension → Viewer | Call | `{ filename: string, as_json?: boolean }` |
+| `language.syntax.get` (response) | Viewer → Extension | Response | `SyntaxCacheFile` |
| `language.syntax.change` | Viewer → Extension | Notification | `SyntaxChange` |
| `script.compiled` | Viewer → Extension | Notification | `CompilationResult` |
| `runtime.debug` | Viewer → Extension | Notification | `RuntimeDebug` |
@@ -85,9 +94,9 @@ This document describes all the message interfaces defined in for WebSocket comm
### SessionHandshake
-**JSON-RPC Method:** `session.handshake` (notification from viewer)
+**JSON-RPC Method:** `session.handshake` (call from viewer)
-The initial handshake message sent by the viewer to establish a connection.
+The initial handshake call sent by the viewer to establish a session.
```typescript
interface SessionHandshake {
@@ -112,10 +121,13 @@ interface SessionHandshake {
- `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
+- `challenge` (optional): Path to a temporary file on the local filesystem containing a UUID. The client must read this file and return the UUID as `challenge_response` to authenticate the connection.
+- `languages`: Array of supported scripting languages (e.g., `["lsl", "luau"]`)
+- `syntax_id`: Current active syntax identifier as a UUID string
+- `features`: Dictionary of feature flags indicating viewer capabilities. Known flags:
+ - `live_sync`: Viewer supports live script synchronisation with the external editor
+ - `compilation`: Viewer will forward compilation results via `script.compiled`
+ - `syntax_cache`: Viewer supports `language.syntax.cache` and `language.syntax.get` for retrieving syntax definition files
### SessionHandshakeResponse
@@ -131,6 +143,8 @@ interface SessionHandshakeResponse {
challenge_response?: string;
languages: string[];
features: { [feature: string]: boolean };
+ script_name?: string;
+ script_language?: string;
}
```
@@ -139,15 +153,17 @@ interface SessionHandshakeResponse {
- `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
+- `challenge_response` (optional): The UUID read from the temporary file identified by the `challenge` field in the handshake. Must be provided if `challenge` was present, otherwise the connection will be closed.
- `languages`: Array of languages supported by the client
- `features`: Dictionary of features supported by the client
+- `script_name` (optional): Name of the script currently open in the editor
+- `script_language` (optional): Language of the script currently open in the editor (e.g. `"lsl"`, `"luau"`)
### 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.
+Confirmation notification sent by the viewer after successful handshake completion. No parameters are sent with this notification.
### SessionDisconnect
@@ -164,7 +180,12 @@ interface SessionDisconnect {
**Fields:**
-- `reason`: Numeric code indicating the reason for disconnection
+- `reason`: Numeric code indicating the reason for disconnection:
+ - `0`: Normal closure
+ - `1`: Editor closed
+ - `2`: Protocol error
+ - `3`: Connection timeout
+ - `4`: Internal server error
- `message`: Human-readable description of the disconnect reason
## Language and Syntax Interfaces
@@ -183,7 +204,7 @@ interface SyntaxChange {
**Fields:**
-- `id`: Identifier for the new syntax/language
+- `id`: UUID string identifying the new syntax version
### Language Syntax ID Request
@@ -191,63 +212,130 @@ interface SyntaxChange {
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.
+**Response:** Returns `{ id: string }` where `id` is the current syntax version as a UUID string.
### Language Syntax Request
**JSON-RPC Method:** `language.syntax` (call from extension to viewer)
-Requests detailed syntax information for a specific language kind.
+Requests the in-memory keyword definitions for a specific language. These definitions are the deserialized, viewer-processed form of the syntax data for the current region.
**Parameters:**
```typescript
{
- kind: string; // The type of syntax information requested
+ kind: string; // The language whose definitions to retrieve
}
```
-**Fields:**
+**Valid `kind` values:**
-- `kind`: The type of syntax information to retrieve (e.g., "functions", "constants", "events", "types.luau")
+| Value | Description |
+| ----------- | ----------------------------------------- |
+| `"defs.lsl"` | Returns the LSL keyword definitions |
+| `"defs.lua"` | Returns the Luau keyword definitions |
-**Response:** Returns `LanguageInfo` data containing the requested syntax information:
+**Response:**
```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 };
- };
+ defs?: object; // Present only on success
+ success: boolean;
+ error?: string; // Present only on failure
+}
+```
+
+**Response Fields:**
+
+- `id`: The current syntax version identifier
+- `defs` (optional): The keyword definitions object. Only present when `success` is `true`. Structure varies by language.
+- `success`: Whether the definitions were found and returned successfully
+- `error` (optional): Human-readable error description. Only present when `success` is `false`
+
+**Error cases:**
+
+- No `kind` parameter supplied: `success: false`, `error: "No syntax category specified"`
+- Unknown `kind` value: `success: false`, `error: "Unknown syntax category requested"`
+
+### Language Syntax Cache List
+
+**JSON-RPC Method:** `language.syntax.cache` (call from extension to viewer)
+
+Requests the list of file names currently held in the `LLSyntaxDefCache`. This provides the extension with the available syntax definition file names that can subsequently be retrieved with `language.syntax.get`. This method takes no parameters.
+
+**Response:**
+
+```typescript
+interface SyntaxCacheList {
+ files: string[]; // Array of file names (e.g. ["lsl_keywords.xml", "slua_definitions.yaml"])
+ success: boolean;
+}
+```
+
+**Response Fields:**
+
+- `files`: Array of file name strings, each of which can be passed as the `filename` parameter to `language.syntax.get`
+- `success`: Whether the request was handled successfully
+
+**Known cache files:**
+
+| File name | Description |
+| -------------------------------- | ---------------------------------------------------- |
+| `builtins.txt` | LSL built-in keyword list in plain text format |
+| `lsl_definitions.yaml` | LSL language definitions in YAML format |
+| `lsl_keywords.xml` | LSL keyword definitions in LLSD XML format |
+| `lsl_keywords_pretty.xml` | LSL keyword definitions in formatted LLSD XML format |
+| `slua_default.d.luau` | Luau type definition file for editor tooling |
+| `slua_default.docs.json` | Luau documentation data in JSON format |
+| `slua_definitions.yaml` | Luau language definitions in YAML format |
+| `slua_keywords.xml` | Luau keyword definitions in LLSD XML format |
+| `slua_keywords_pretty.xml` | Luau keyword definitions in formatted LLSD XML format |
+| `slua_selene.yml` | Luau Selene linter configuration in YAML format |
+
+Not all files may be present in every cache — the actual list returned by `language.syntax.cache` reflects only what is available on the viewer's local filesystem at the time of the request.
+
+### Language Syntax Cache Get
+
+**JSON-RPC Method:** `language.syntax.get` (call from extension to viewer)
+
+Requests the content of a specific file from the syntax definition cache. The file name must be one of the names returned by a prior `language.syntax.cache` call. Content is returned either as a raw text string or as a parsed JSON/LLSD object depending on the `as_json` parameter.
+
+**Parameters:**
+
+```typescript
+{
+ filename: string; // The file name to retrieve, as returned by language.syntax.cache
+ as_json?: boolean; // Optional. If true, content is returned as a parsed object rather than raw text
+}
+```
+
+**Fields:**
+
+- `filename`: The file name to retrieve (e.g. `"lsl_keywords.xml"`, `"slua_definitions.yaml"`)
+- `as_json` (optional): When `true`, the file is deserialized and returned as a structured object in `content`. When omitted or `false`, `content` is the raw text of the file.
+
+**Response:**
+
+```typescript
+interface SyntaxCacheFile {
+ content?: string | object; // Present only on success. String if as_json is false/omitted, object if as_json is true
+ success: boolean;
+ error?: string; // Present only on failure
}
```
**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
+- `content`: The file content. Only present when `success` is `true`. Is a raw text string when `as_json` is omitted or `false`; is a parsed object when `as_json` is `true`.
+- `success`: Whether the file was found and read successfully
+- `error` (optional): Human-readable error description. Only present when `success` is `false`
-The specific sections returned depend on the `kind` parameter and the active language context.
+**Error cases:**
+
+- No `filename` parameter supplied: `success: false`, `error: "No filename specified"`
+- Name not found in cache: `success: false`, `error: "Requested syntax cache file not found"`
+- File could not be loaded: `success: false`, `error: "Failed to load syntax cache file"` (or `"Failed to load and format syntax cache file."` when `as_json` is `true`)
## Script Subscription Interfaces
@@ -283,7 +371,6 @@ interface ScriptSubscribeResponse {
success: boolean;
status: number;
object_id?: string;
- object_name?: string;
item_id?: string;
message?: string;
}
@@ -293,9 +380,14 @@ interface ScriptSubscribeResponse {
- `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.
+- `status`: Numeric status code indicating the result:
+ - `0`: Success
+ - `1`: Invalid editor — the script editor panel is no longer open
+ - `2`: Invalid subscription — no subscription found for the given `script_id`
+ - `3`: Already subscribed — another connection is already subscribed to this script
+ - `4`: Internal server error
+- `object_id` (optional): The in-world UUID of the object containing the script
+- `item_id` (optional): The inventory item UUID of the script within the object
- `message` (optional): Additional information about the subscription result
### ScriptUnsubscribe
@@ -314,6 +406,28 @@ interface ScriptUnsubscribe {
- `script_id`: Unique identifier for the script to unsubscribe from
+### ScriptList
+
+**JSON-RPC Method:** `script.list` (call from extension to viewer)
+
+Requests the list of all scripts currently open and tracked by the viewer, along with the viewer's temp directory. This is intended for use by a file watcher tool that needs to discover which script temp files are active without going through the full `script.subscribe` flow. This method takes no parameters.
+
+**Response:**
+
+```typescript
+interface ScriptList {
+ temp_dir: string;
+ script_ids: string[];
+ success: boolean;
+}
+```
+
+**Response Fields:**
+
+- `temp_dir`: The absolute path to the viewer's temp directory where live-sync script files are written. Combined with a `script_id`, the caller can locate the corresponding temp file on disk.
+- `script_ids`: Array of script ID strings for all currently subscribed scripts, across all active connections.
+- `success`: Always `true`.
+
## Compilation Interfaces
### CompilationError
@@ -324,17 +438,19 @@ Individual compilation error record.
interface CompilationError {
row: number;
column: number;
- level: "ERROR";
+ level: string;
message: string;
+ format?: "lsl"; // Present only for LSL compilation errors
}
```
**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)
+- `row`: Line number where the error occurred (1-based for both LSL and Luau)
+- `column`: Column position of the error (1-based for LSL; always `0` for Luau as the compiler does not provide column information)
+- `level`: Compiler severity string (e.g. `"ERROR"`, `"WARNING"`)
- `message`: Error description
+- `format` (optional): Present and set to `"lsl"` for LSL compilation errors; absent for Luau errors
### CompilationResult
@@ -405,10 +521,10 @@ interface RuntimeError {
- `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
+- `message`: The full raw chat text of the runtime error message as received from the simulator
+- `error`: Extracted error description. Currently always an empty string — runtime error extraction from the simulator's multi-message format is not yet fully implemented.
+- `line`: Line number where the error occurred. Currently always `0` for the same reason.
+- `stack` (optional): Stack trace lines if they could be extracted from the error message
## Handler and Configuration Interfaces
@@ -436,7 +552,7 @@ interface WebSocketHandlers {
- `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
+- `onSubscribe`: Handler called when the extension sends a `script.subscribe` request, returns subscription response
- `onUnsubscribe`: Handler for script unsubscription notifications from viewer
- `onSyntaxChange`: Handler for syntax change notifications
- `onConnectionClosed`: Handler called when connection is closed
diff --git a/indra/cmake/LSLDefinitions.cmake b/indra/cmake/LSLDefinitions.cmake
index ae0eeebb7e..1a9a477118 100644
--- a/indra/cmake/LSLDefinitions.cmake
+++ b/indra/cmake/LSLDefinitions.cmake
@@ -3,7 +3,7 @@ include(Prebuilt)
use_prebuilt_binary(lsl_definitions)
-configure_file("${AUTOBUILD_INSTALL_DIR}/lsl_definitions/lsl_keywords_pretty.xml"
+configure_file("${AUTOBUILD_INSTALL_DIR}/lsl_definitions/lsl_keywords.xml"
"${CMAKE_SOURCE_DIR}/newview/app_settings/keywords_lsl_default.xml" COPYONLY)
-configure_file("${AUTOBUILD_INSTALL_DIR}/lsl_definitions/slua_keywords_pretty.xml"
+configure_file("${AUTOBUILD_INSTALL_DIR}/lsl_definitions/lua_keywords.xml"
"${CMAKE_SOURCE_DIR}/newview/app_settings/keywords_lua_default.xml" COPYONLY)
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index b24e5e4fcc..f18af1f18e 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -39,7 +39,7 @@
#include "llfilesystem.h"
#include "message.h" // for getting the port
-
+#include "llstl.h"
using namespace LLCore;
@@ -112,15 +112,17 @@ bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd)
{
// Convert response to LLSD
BufferArray * body(response->getBody());
- if (!body || !body->size())
+ size_t body_size(body ? body->size() : 0);
+ if (!body || !body_size)
{
return false;
}
LLCore::BufferArrayStream bas(body);
LLSD body_llsd;
- S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas, log));
- if (LLSDParser::PARSE_FAILURE == parse_status){
+
+ if (!LLSDSerialize::deserialize(body_llsd, bas, body_size))
+ {
return false;
}
out_llsd = body_llsd;
@@ -409,28 +411,6 @@ LLSD HttpCoroLLSDHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
result = parseBody(response, success);
-#if 0
- bool parsed = !((response->getBodySize() == 0) ||
- !LLCoreHttpUtil::responseToLLSD(response, emit_parse_errors, result));
-
- if (!parsed)
- {
- // Only emit a warning if we failed to parse when 'content-type' == 'application/llsd+xml'
- LLCore::HttpHeaders::ptr_t headers(response->getHeaders());
- const std::string *contentType = (headers) ? headers->find(HTTP_IN_HEADER_CONTENT_TYPE) : NULL;
-
- if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType))
- {
- std::string thebody = LLCoreHttpUtil::responseToString(response);
- LL_WARNS("CoreHTTP") << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] "
- << " body: " << thebody << LL_ENDL;
-
- // Replace the status with a new one indicating the failure.
- status = LLCore::HttpStatus(499, "Failed to deserialize LLSD.");
- }
- }
-#endif
-
if (!success)
{
#if 1
@@ -955,7 +935,6 @@ LLSD HttpCoroutineAdapter::getJsonAndSuspend(LLCore::HttpRequest::ptr_t request,
return getAndSuspend_(request, url, options, headers, httpHandler);
}
-
LLSD HttpCoroutineAdapter::getAndSuspend_(LLCore::HttpRequest::ptr_t &request,
const std::string & url,
LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers,
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index 3dbfd6f00d..8fa638fd6e 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -483,7 +483,6 @@ public:
headers);
}
-
/// Execute a DELETE transaction on the supplied URL and yield execution of
/// the coroutine until a result is available.
///
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 4be89df283..bd2b484e7a 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1687,7 +1687,6 @@ 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
app_settings/message.xml
${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
diff --git a/indra/newview/app_settings/types_lua_default.xml b/indra/newview/app_settings/types_lua_default.xml
deleted file mode 100644
index cb40ec3d06..0000000000
--- a/indra/newview/app_settings/types_lua_default.xml
+++ /dev/null
@@ -1,5262 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<llsd>
-<map>
- <key>version</key>
- <string>1.0.0</string>
- <key>typeAliases</key>
- <array>
- <map>
- <key>name</key>
- <string>rotation</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>reference</string>
- <key>name</key>
- <string>quaternion</string>
- </map>
- <key>comment</key>
- <string>'rotation' is an alias for 'quaternion'</string>
- </map>
- <map>
- <key>name</key>
- <string>numeric</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>union</string>
- <key>types</key>
- <array>
- <string>boolean</string>
- <string>number</string>
- </array>
- </map>
- </map>
- <map>
- <key>name</key>
- <string>list</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>array</string>
- <key>elementType</key>
- <map>
- <key>kind</key>
- <string>union</string>
- <key>types</key>
- <array>
- <string>string</string>
- <string>number</string>
- <string>vector</string>
- <string>uuid</string>
- <string>quaternion</string>
- <string>boolean</string>
- </array>
- </map>
- </map>
- </map>
- <map>
- <key>name</key>
- <string>LLDetectedEventName</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>literal-union</string>
- <key>values</key>
- <array/>
- </map>
- </map>
- <map>
- <key>name</key>
- <string>LLNonDetectedEventName</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>literal-union</string>
- <key>values</key>
- <array/>
- </map>
- </map>
- <map>
- <key>name</key>
- <string>LLEventName</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>union</string>
- <key>types</key>
- <array>
- <string>LLDetectedEventName</string>
- <string>LLNonDetectedEventName</string>
- </array>
- </map>
- </map>
- <map>
- <key>name</key>
- <string>LLEventHandler</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>any</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- </map>
- </map>
- <map>
- <key>name</key>
- <string>LLDetectedEventHandler</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>detected</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>array</string>
- <key>elementType</key>
- <string>LLDetectedEvent</string>
- </map>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- </map>
- </map>
- <map>
- <key>name</key>
- <string>LLTimerEveryCallback</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>scheduled</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>interval</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- </map>
- <key>comment</key>
- <string>Callback type for LLTimers.every() - receives scheduled time and interval</string>
- </map>
- <map>
- <key>name</key>
- <string>LLTimerOnceCallback</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>scheduled</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- </map>
- <key>comment</key>
- <string>Callback type for LLTimers.once() - receives scheduled time</string>
- </map>
- <map>
- <key>name</key>
- <string>LLTimerCallback</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>union</string>
- <key>types</key>
- <array>
- <string>LLTimerEveryCallback</string>
- <string>LLTimerOnceCallback</string>
- <string>(...any) -&gt; ...any</string>
- </array>
- </map>
- <key>comment</key>
- <string>Union of timer callback types</string>
- </map>
- <map>
- <key>name</key>
- <string>OsDateTime</string>
- <key>definition</key>
- <map>
- <key>kind</key>
- <string>table</string>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>year</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>month</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>day</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>hour</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>min</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>sec</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>wday</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>yday</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>isdst</string>
- <key>type</key>
- <string>boolean</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- </map>
- <key>comment</key>
- <string>Date/time table structure used by os.date and os.time</string>
- </map>
- </array>
- <key>classes</key>
- <array>
- <map>
- <key>name</key>
- <string>quaternion</string>
- <key>comment</key>
- <string>Luau Type Definition for LSL UserData Type: quaternion</string>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>z</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>methods</key>
- <array>
- <map>
- <key>name</key>
- <string>__add</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>__sub</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>__mul</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>__div</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>__unm</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>__eq</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>boolean</string>
- </map>
- <map>
- <key>name</key>
- <string>__tostring</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>uuid</string>
- <key>comment</key>
- <string>Luau Type Definition for LSL UserData Type: uuid</string>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>istruthy</string>
- <key>type</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Returns true if the UUID is not the null UUID (all zeros)</string>
- </map>
- <map>
- <key>name</key>
- <string>bytes</string>
- <key>type</key>
- <string>string?</string>
- <key>comment</key>
- <string>Returns the raw 16-byte binary string of the UUID, or nil if the UUID is not in a compressed state</string>
- </map>
- </array>
- <key>methods</key>
- <array>
- <map>
- <key>name</key>
- <string>__tostring</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>vector</string>
- <key>comment</key>
- <string>Luau Type Definition for LSL UserData Type: vector</string>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>z</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>methods</key>
- <array>
- <map>
- <key>name</key>
- <string>__add</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- <key>comment</key>
- <string>Native component-wise addition</string>
- </map>
- <map>
- <key>name</key>
- <string>__sub</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- <key>comment</key>
- <string>Native component-wise subtraction</string>
- </map>
- <map>
- <key>name</key>
- <string>__unm</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- <key>comment</key>
- <string>Unary negation</string>
- </map>
- <map>
- <key>name</key>
- <string>__mul</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>number | vector | quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- <key>comment</key>
- <string>Multiplication: vector * number or vector * vector -&gt; vector, vector * quaternion -&gt; vector (Rotation)</string>
- </map>
- <map>
- <key>name</key>
- <string>__div</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>number | vector | quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- <key>comment</key>
- <string>Division: vector / number or vector / vector -&gt; vector (Scale), vector / quaternion -&gt; vector (Rotation by inverse)</string>
- </map>
- <map>
- <key>name</key>
- <string>__mod</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>other</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- <key>comment</key>
- <string>LSL-style modulo: vector % vector -&gt; vector (Cross Product)</string>
- </map>
- <map>
- <key>name</key>
- <string>__tostring</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>LLDetectedEvent</string>
- <key>comment</key>
- <string>Event detection class providing access to detected object/avatar information</string>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>index</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>valid</string>
- <key>type</key>
- <string>boolean</string>
- </map>
- <map>
- <key>name</key>
- <string>canAdjustDamage</string>
- <key>type</key>
- <string>boolean</string>
- </map>
- </array>
- <key>methods</key>
- <array/>
- </map>
- <map>
- <key>name</key>
- <string>LLEvents</string>
- <key>comment</key>
- <string>Event registration and management class for Second Life events</string>
- <key>methods</key>
- <array>
- <map>
- <key>name</key>
- <string>on</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>event</string>
- <key>type</key>
- <string>LLEventName</string>
- </map>
- <map>
- <key>name</key>
- <string>callback</string>
- <key>type</key>
- <string>LLEventHandler</string>
- </map>
- </array>
- <key>returnType</key>
- <string>LLEventHandler</string>
- <key>comment</key>
- <string>Registers a callback for an event. Returns the callback.</string>
- </map>
- <map>
- <key>name</key>
- <string>off</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>event</string>
- <key>type</key>
- <string>LLEventName</string>
- </map>
- <map>
- <key>name</key>
- <string>callback</string>
- <key>type</key>
- <string>LLEventHandler</string>
- </map>
- </array>
- <key>returnType</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Unregisters a callback. Returns true if found and removed.</string>
- </map>
- <map>
- <key>name</key>
- <string>once</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>event</string>
- <key>type</key>
- <string>LLEventName</string>
- </map>
- <map>
- <key>name</key>
- <string>callback</string>
- <key>type</key>
- <string>LLEventHandler</string>
- </map>
- </array>
- <key>returnType</key>
- <string>LLEventHandler</string>
- <key>comment</key>
- <string>Registers a one-time callback. Returns the wrapper function.</string>
- </map>
- <map>
- <key>name</key>
- <string>listeners</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>event</string>
- <key>type</key>
- <string>LLEventName</string>
- </map>
- </array>
- <key>returnType</key>
- <string>{LLEventHandler}</string>
- <key>comment</key>
- <string>Returns a list of all listeners for a specific event.</string>
- </map>
- <map>
- <key>name</key>
- <string>eventNames</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- </array>
- <key>returnType</key>
- <string>{string}</string>
- <key>comment</key>
- <string>Returns a list of all event names that have listeners.</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>LLTimers</string>
- <key>comment</key>
- <string>Timer management class for scheduling periodic and one-time callbacks</string>
- <key>methods</key>
- <array>
- <map>
- <key>name</key>
- <string>every</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>seconds</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>callback</string>
- <key>type</key>
- <string>LLTimerEveryCallback</string>
- </map>
- </array>
- <key>returnType</key>
- <string>LLTimerCallback</string>
- <key>comment</key>
- <string>Registers a callback to be called every N seconds. Returns the callback.</string>
- </map>
- <map>
- <key>name</key>
- <string>once</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>seconds</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>callback</string>
- <key>type</key>
- <string>LLTimerOnceCallback</string>
- </map>
- </array>
- <key>returnType</key>
- <string>LLTimerCallback</string>
- <key>comment</key>
- <string>Registers a callback to be called once after N seconds. Returns the callback.</string>
- </map>
- <map>
- <key>name</key>
- <string>off</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>self</string>
- </map>
- <map>
- <key>name</key>
- <string>callback</string>
- <key>type</key>
- <string>LLTimerCallback</string>
- </map>
- </array>
- <key>returnType</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Unregisters a timer callback. Returns true if found and removed.</string>
- </map>
- </array>
- </map>
- </array>
- <key>globalVariables</key>
- <array>
- <map>
- <key>name</key>
- <string>quaternion</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>callable-table</string>
- <key>tableType</key>
- <map>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>create</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>z</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <key>comment</key>
- <string>Constructor</string>
- </map>
- <map>
- <key>name</key>
- <string>identity</string>
- <key>type</key>
- <string>quaternion</string>
- <key>comment</key>
- <string>Identity quaternion constant</string>
- </map>
- <map>
- <key>name</key>
- <string>normalize</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>q</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <key>comment</key>
- <string>Returns normalized quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>magnitude</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>q</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- </map>
- <key>comment</key>
- <string>Returns magnitude of quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>dot</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>a</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- </map>
- <key>comment</key>
- <string>Dot product of two quaternions</string>
- </map>
- <map>
- <key>name</key>
- <string>slerp</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>a</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <key>comment</key>
- <string>Spherical linear interpolation</string>
- </map>
- <map>
- <key>name</key>
- <string>conjugate</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>q</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- <key>comment</key>
- <string>Returns conjugate of quaternion</string>
- </map>
- <map>
- <key>name</key>
- <string>tofwd</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>q</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Returns forward vector from quaternion rotation</string>
- </map>
- <map>
- <key>name</key>
- <string>toleft</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>q</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Returns left vector from quaternion rotation</string>
- </map>
- <map>
- <key>name</key>
- <string>toup</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>q</string>
- <key>type</key>
- <string>quaternion</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Returns up vector from quaternion rotation</string>
- </map>
- </array>
- </map>
- <key>callSignature</key>
- <map>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>z</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion</string>
- </map>
- </map>
- <key>comment</key>
- <string>Global 'quaternion' library table with callable metatable</string>
- </map>
- <map>
- <key>name</key>
- <string>rotation</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>typeof</string>
- <key>target</key>
- <string>quaternion</string>
- </map>
- <key>comment</key>
- <string>'rotation' global is an alias to the 'quaternion' library</string>
- </map>
- <map>
- <key>name</key>
- <string>uuid</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>callable-table</string>
- <key>tableType</key>
- <map>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>create</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>union</string>
- <key>types</key>
- <array>
- <string>string</string>
- <string>buffer</string>
- <string>uuid</string>
- </array>
- </map>
- </map>
- </array>
- <key>returnType</key>
- <string>uuid?</string>
- </map>
- <key>comment</key>
- <string>Creates a new uuid from a string, buffer, or existing uuid</string>
- </map>
- </array>
- </map>
- <key>callSignature</key>
- <map>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>union</string>
- <key>types</key>
- <array>
- <string>string</string>
- <string>buffer</string>
- <string>uuid</string>
- </array>
- </map>
- </map>
- </array>
- <key>returnType</key>
- <string>uuid?</string>
- </map>
- </map>
- <key>comment</key>
- <string>Global 'uuid' library table</string>
- </map>
- <map>
- <key>name</key>
- <string>vector</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>callable-table</string>
- <key>tableType</key>
- <map>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>create</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>z</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Creates a new vector with the given component values</string>
- </map>
- <map>
- <key>name</key>
- <string>magnitude</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- </map>
- <key>comment</key>
- <string>Calculates the magnitude of a given vector</string>
- </map>
- <map>
- <key>name</key>
- <string>normalize</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Computes the normalized version (unit vector) of a given vector</string>
- </map>
- <map>
- <key>name</key>
- <string>cross</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>a</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Computes the cross product of two vectors</string>
- </map>
- <map>
- <key>name</key>
- <string>dot</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>a</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- </map>
- <key>comment</key>
- <string>Computes the dot product of two vectors</string>
- </map>
- <map>
- <key>name</key>
- <string>angle</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>a</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>name</key>
- <string>axis</string>
- <key>type</key>
- <string>vector</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- </map>
- <key>comment</key>
- <string>Computes the angle between two vectors in radians</string>
- </map>
- <map>
- <key>name</key>
- <string>floor</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Applies math.floor to every component of the input vector</string>
- </map>
- <map>
- <key>name</key>
- <string>ceil</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Applies math.ceil to every component of the input vector</string>
- </map>
- <map>
- <key>name</key>
- <string>abs</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Applies math.abs to every component of the input vector</string>
- </map>
- <map>
- <key>name</key>
- <string>sign</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Applies math.sign to every component of the input vector</string>
- </map>
- <map>
- <key>name</key>
- <string>clamp</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>name</key>
- <string>min</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>name</key>
- <string>max</string>
- <key>type</key>
- <string>vector</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Applies math.clamp to every component of the input vector</string>
- </map>
- <map>
- <key>name</key>
- <string>max</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>type</key>
- <string>vector</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Applies math.max to the corresponding components of the input vectors</string>
- </map>
- <map>
- <key>name</key>
- <string>min</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>type</key>
- <string>vector</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Applies math.min to the corresponding components of the input vectors</string>
- </map>
- <map>
- <key>name</key>
- <string>lerp</string>
- <key>type</key>
- <map>
- <key>kind</key>
- <string>function</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>a</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>vector</string>
- </map>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- <key>comment</key>
- <string>Linear interpolation between two vectors</string>
- </map>
- <map>
- <key>name</key>
- <string>zero</string>
- <key>type</key>
- <string>vector</string>
- <key>comment</key>
- <string>A zero vector &lt;0,0,0&gt;</string>
- </map>
- <map>
- <key>name</key>
- <string>one</string>
- <key>type</key>
- <string>vector</string>
- <key>comment</key>
- <string>A one vector &lt;1,1,1&gt;</string>
- </map>
- </array>
- </map>
- <key>callSignature</key>
- <map>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>z</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>vector</string>
- </map>
- </map>
- <key>comment</key>
- <string>Global 'vector' library table</string>
- </map>
- <map>
- <key>name</key>
- <string>LLEvents</string>
- <key>type</key>
- <string>LLEvents</string>
- <key>comment</key>
- <string>Second Life event management and registration</string>
- </map>
- <map>
- <key>name</key>
- <string>LLTimers</string>
- <key>type</key>
- <string>LLTimers</string>
- <key>comment</key>
- <string>Second Life timer management and scheduling</string>
- </map>
- <map>
- <key>name</key>
- <string>loadstring</string>
- <key>type</key>
- <string>nil</string>
- <key>comment</key>
- <string>loadstring is removed in SLua</string>
- </map>
- <map>
- <key>name</key>
- <string>getfenv</string>
- <key>type</key>
- <string>nil</string>
- <key>comment</key>
- <string>getfenv is removed in SLua</string>
- </map>
- <map>
- <key>name</key>
- <string>setfenv</string>
- <key>type</key>
- <string>nil</string>
- <key>comment</key>
- <string>setfenv is removed in SLua</string>
- </map>
- </array>
- <key>modules</key>
- <array>
- <map>
- <key>name</key>
- <string>bit32</string>
- <key>comment</key>
- <string>Bitwise operations library</string>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>arshift</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>disp</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Arithmetic right shift</string>
- </map>
- <map>
- <key>name</key>
- <string>band</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>number</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Bitwise AND of all arguments</string>
- </map>
- <map>
- <key>name</key>
- <string>bnot</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Bitwise NOT</string>
- </map>
- <map>
- <key>name</key>
- <string>bor</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>number</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Bitwise OR of all arguments</string>
- </map>
- <map>
- <key>name</key>
- <string>bxor</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>number</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Bitwise XOR of all arguments</string>
- </map>
- <map>
- <key>name</key>
- <string>btest</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>number</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Returns true if bitwise AND of all arguments is not zero</string>
- </map>
- <map>
- <key>name</key>
- <string>extract</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>field</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>width</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Extracts bits from n at position field with width</string>
- </map>
- <map>
- <key>name</key>
- <string>lrotate</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>disp</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Left rotate</string>
- </map>
- <map>
- <key>name</key>
- <string>lshift</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>disp</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Left shift</string>
- </map>
- <map>
- <key>name</key>
- <string>replace</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>v</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>field</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>width</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Replaces bits in n at position field with width using value v</string>
- </map>
- <map>
- <key>name</key>
- <string>rrotate</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>disp</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Right rotate</string>
- </map>
- <map>
- <key>name</key>
- <string>rshift</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>disp</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Right shift</string>
- </map>
- <map>
- <key>name</key>
- <string>countlz</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Count leading zeros</string>
- </map>
- <map>
- <key>name</key>
- <string>countrz</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Count trailing zeros</string>
- </map>
- <map>
- <key>name</key>
- <string>byteswap</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Swap byte order</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>buffer</string>
- <key>comment</key>
- <string>Buffer manipulation library for binary data</string>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>create</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>size</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>buffer</string>
- <key>comment</key>
- <string>Creates a new buffer of the specified size</string>
- </map>
- <map>
- <key>name</key>
- <string>fromstring</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>str</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>buffer</string>
- <key>comment</key>
- <string>Creates a buffer from a string</string>
- </map>
- <map>
- <key>name</key>
- <string>tostring</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Converts buffer to string</string>
- </map>
- <map>
- <key>name</key>
- <string>readi8</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read signed 8-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>readu8</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read unsigned 8-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>readi16</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read signed 16-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>readu16</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read unsigned 16-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>readi32</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read signed 32-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>readu32</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read unsigned 32-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>readf32</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read 32-bit float</string>
- </map>
- <map>
- <key>name</key>
- <string>readf64</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read 64-bit float</string>
- </map>
- <map>
- <key>name</key>
- <string>writei8</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write signed 8-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>writeu8</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write unsigned 8-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>writei16</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write signed 16-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>writeu16</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write unsigned 16-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>writei32</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write signed 32-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>writeu32</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write unsigned 32-bit integer</string>
- </map>
- <map>
- <key>name</key>
- <string>writef32</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write 32-bit float</string>
- </map>
- <map>
- <key>name</key>
- <string>writef64</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write 64-bit float</string>
- </map>
- <map>
- <key>name</key>
- <string>readstring</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>count</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Read string from buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>writestring</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>count</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write string to buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>len</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the length of the buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>copy</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>target</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>targetOffset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>source</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>sourceOffset</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>count</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Copy data from source buffer to target buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>fill</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>count</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Fill buffer with a value</string>
- </map>
- <map>
- <key>name</key>
- <string>readbits</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>bitOffset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>bitCount</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Read bits from buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>writebits</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>buffer</string>
- </map>
- <map>
- <key>name</key>
- <string>bitOffset</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>bitCount</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Write bits to buffer</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>coroutine</string>
- <key>comment</key>
- <string>Coroutine manipulation library</string>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>create</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>f</string>
- <key>type</key>
- <string>(...any) -&gt; ...any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>thread</string>
- <key>comment</key>
- <string>Creates a new coroutine from a function</string>
- </map>
- <map>
- <key>name</key>
- <string>resume</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>co</string>
- <key>type</key>
- <string>thread</string>
- </map>
- <map>
- <key>type</key>
- <string>any</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>(boolean, ...any)</string>
- <key>comment</key>
- <string>Resumes a coroutine, returns success and results</string>
- </map>
- <map>
- <key>name</key>
- <string>running</string>
- <key>parameters</key>
- <array/>
- <key>returnType</key>
- <string>thread?</string>
- <key>comment</key>
- <string>Returns the running coroutine, or nil if called from main thread</string>
- </map>
- <map>
- <key>name</key>
- <string>status</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>co</string>
- <key>type</key>
- <string>thread</string>
- </map>
- </array>
- <key>returnType</key>
- <string>&quot;running&quot; | &quot;suspended&quot; | &quot;normal&quot; | &quot;dead&quot;</string>
- <key>comment</key>
- <string>Returns the status of a coroutine</string>
- </map>
- <map>
- <key>name</key>
- <string>wrap</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>f</string>
- <key>type</key>
- <string>(...any) -&gt; ...any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>(...any) -&gt; ...any</string>
- <key>comment</key>
- <string>Creates a coroutine and returns a function that resumes it</string>
- </map>
- <map>
- <key>name</key>
- <string>yield</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>any</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>...any</string>
- <key>comment</key>
- <string>Suspends the coroutine and returns values to resume</string>
- </map>
- <map>
- <key>name</key>
- <string>isyieldable</string>
- <key>parameters</key>
- <array/>
- <key>returnType</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Returns true if the coroutine can yield</string>
- </map>
- <map>
- <key>name</key>
- <string>close</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>co</string>
- <key>type</key>
- <string>thread</string>
- </map>
- </array>
- <key>returnType</key>
- <string>(boolean, string?)</string>
- <key>comment</key>
- <string>Closes a coroutine, returns success and optional error message</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>debug</string>
- <key>comment</key>
- <string>Debug library for introspection</string>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>info</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>thread</string>
- <key>type</key>
- <string>thread</string>
- </map>
- <map>
- <key>name</key>
- <string>level</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>options</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>...any</string>
- <key>comment</key>
- <string>Returns information about a function or stack level</string>
- <key>overloads</key>
- <array>
- <map>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>level</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>options</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>...any</string>
- <key>comment</key>
- <string>Returns information about a stack level</string>
- </map>
- <map>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>func</string>
- <key>type</key>
- <string>(...any) -&gt; ...any</string>
- </map>
- <map>
- <key>name</key>
- <string>options</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>...any</string>
- <key>comment</key>
- <string>Returns information about a function</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>traceback</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>thread</string>
- <key>type</key>
- <string>thread</string>
- </map>
- <map>
- <key>name</key>
- <string>message</string>
- <key>type</key>
- <string>string</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>level</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Returns a string with a traceback of the call stack</string>
- <key>overloads</key>
- <array>
- <map>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>message</string>
- <key>type</key>
- <string>string</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>level</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Returns a string with a traceback of the current call stack</string>
- </map>
- </array>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>llbase64</string>
- <key>comment</key>
- <string>Base64 encoding/decoding library</string>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>encode</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>data</string>
- <key>type</key>
- <string>string | buffer</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Encodes a string or buffer to base64</string>
- </map>
- <map>
- <key>name</key>
- <string>decode</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>data</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Decodes a base64 string to a string</string>
- <key>overloads</key>
- <array>
- <map>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>data</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>asBuffer</string>
- <key>type</key>
- <string>boolean</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string | buffer</string>
- <key>comment</key>
- <string>Decodes a base64 string to a string or buffer</string>
- </map>
- </array>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>lljson</string>
- <key>comment</key>
- <string>JSON encoding/decoding library for Second Life</string>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>null</string>
- <key>type</key>
- <string>any</string>
- <key>comment</key>
- <string>A constant to pass for null to json encode</string>
- </map>
- <map>
- <key>name</key>
- <string>empty_array_mt</string>
- <key>type</key>
- <string>{ [any]: any }</string>
- <key>comment</key>
- <string>Metatable for declaring table as an empty array for json encode</string>
- </map>
- <map>
- <key>name</key>
- <string>array_mt</string>
- <key>type</key>
- <string>{ [any]: any }</string>
- <key>comment</key>
- <string>Metatable for declaring table as an array for json encode</string>
- </map>
- <map>
- <key>name</key>
- <string>empty_array</string>
- <key>type</key>
- <string>any</string>
- <key>comment</key>
- <string>A constant to pass for an empty array to json encode</string>
- </map>
- <map>
- <key>name</key>
- <string>_NAME</string>
- <key>type</key>
- <string>string</string>
- <key>comment</key>
- <string>Name of the lljson library</string>
- </map>
- <map>
- <key>name</key>
- <string>_VERSION</string>
- <key>type</key>
- <string>string</string>
- <key>comment</key>
- <string>Version of the lljson library</string>
- </map>
- </array>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>encode</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Encodes a Lua value as JSON</string>
- </map>
- <map>
- <key>name</key>
- <string>decode</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>json</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>any</string>
- <key>comment</key>
- <string>Decodes a JSON string to a Lua value</string>
- </map>
- <map>
- <key>name</key>
- <string>slencode</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>any</string>
- </map>
- <map>
- <key>name</key>
- <string>tight</string>
- <key>type</key>
- <string>boolean</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Encodes a Lua value as JSON preserving SL types. Use tight to encode more compactly.</string>
- </map>
- <map>
- <key>name</key>
- <string>sldecode</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>json</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>any</string>
- <key>comment</key>
- <string>Decodes a JSON string to a Lua value preserving SL types</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>math</string>
- <key>comment</key>
- <string>Mathematical functions library</string>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>pi</string>
- <key>type</key>
- <string>number</string>
- <key>comment</key>
- <string>The value of pi</string>
- </map>
- <map>
- <key>name</key>
- <string>huge</string>
- <key>type</key>
- <string>number</string>
- <key>comment</key>
- <string>A value larger than any other numeric value (infinity)</string>
- </map>
- </array>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>abs</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the absolute value of x</string>
- </map>
- <map>
- <key>name</key>
- <string>acos</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the arc cosine of x (in radians)</string>
- </map>
- <map>
- <key>name</key>
- <string>asin</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the arc sine of x (in radians)</string>
- </map>
- <map>
- <key>name</key>
- <string>atan</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the arc tangent of x (in radians)</string>
- </map>
- <map>
- <key>name</key>
- <string>atan2</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the arc tangent of y/x (in radians), using the signs to determine the quadrant</string>
- </map>
- <map>
- <key>name</key>
- <string>ceil</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the smallest integer larger than or equal to x</string>
- </map>
- <map>
- <key>name</key>
- <string>clamp</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>min</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>max</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns n clamped between min and max</string>
- </map>
- <map>
- <key>name</key>
- <string>cos</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the cosine of x (x in radians)</string>
- </map>
- <map>
- <key>name</key>
- <string>cosh</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the hyperbolic cosine of x</string>
- </map>
- <map>
- <key>name</key>
- <string>deg</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Converts x from radians to degrees</string>
- </map>
- <map>
- <key>name</key>
- <string>exp</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns e^x</string>
- </map>
- <map>
- <key>name</key>
- <string>floor</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the largest integer smaller than or equal to x</string>
- </map>
- <map>
- <key>name</key>
- <string>fmod</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the remainder of x/y that rounds towards zero</string>
- </map>
- <map>
- <key>name</key>
- <string>frexp</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>(number, number)</string>
- <key>comment</key>
- <string>Returns m and e such that x = m * 2^e</string>
- </map>
- <map>
- <key>name</key>
- <string>ldexp</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>m</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>e</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns m * 2^e</string>
- </map>
- <map>
- <key>name</key>
- <string>lerp</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>a</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>b</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Linear interpolation between a and b by t</string>
- </map>
- <map>
- <key>name</key>
- <string>log</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>base</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the logarithm of x in the given base (default e)</string>
- </map>
- <map>
- <key>name</key>
- <string>log10</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the base-10 logarithm of x</string>
- </map>
- <map>
- <key>name</key>
- <string>map</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>inMin</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>inMax</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>outMin</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>outMax</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Maps x from input range to output range</string>
- </map>
- <map>
- <key>name</key>
- <string>max</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>type</key>
- <string>number</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the maximum value among the arguments</string>
- </map>
- <map>
- <key>name</key>
- <string>min</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>type</key>
- <string>number</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the minimum value among the arguments</string>
- </map>
- <map>
- <key>name</key>
- <string>modf</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>(number, number)</string>
- <key>comment</key>
- <string>Returns the integer and fractional parts of x</string>
- </map>
- <map>
- <key>name</key>
- <string>noise</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>y</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>z</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns Perlin noise value for the given coordinates</string>
- </map>
- <map>
- <key>name</key>
- <string>pow</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>base</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>exponent</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns base^exponent</string>
- </map>
- <map>
- <key>name</key>
- <string>rad</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Converts x from degrees to radians</string>
- </map>
- <map>
- <key>name</key>
- <string>random</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>m</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns a pseudo-random number</string>
- </map>
- <map>
- <key>name</key>
- <string>randomseed</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>seed</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Sets the seed for the pseudo-random generator</string>
- </map>
- <map>
- <key>name</key>
- <string>round</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns x rounded to the nearest integer</string>
- </map>
- <map>
- <key>name</key>
- <string>sign</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns -1, 0, or 1 depending on the sign of x</string>
- </map>
- <map>
- <key>name</key>
- <string>sin</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the sine of x (x in radians)</string>
- </map>
- <map>
- <key>name</key>
- <string>sinh</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the hyperbolic sine of x</string>
- </map>
- <map>
- <key>name</key>
- <string>sqrt</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the square root of x</string>
- </map>
- <map>
- <key>name</key>
- <string>tan</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the tangent of x (x in radians)</string>
- </map>
- <map>
- <key>name</key>
- <string>tanh</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the hyperbolic tangent of x</string>
- </map>
- <map>
- <key>name</key>
- <string>isnan</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Returns true if x is NaN</string>
- </map>
- <map>
- <key>name</key>
- <string>isinf</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Returns true if x is infinite</string>
- </map>
- <map>
- <key>name</key>
- <string>isfinite</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>x</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Returns true if x is finite</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>os</string>
- <key>comment</key>
- <string>Operating system facilities library</string>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>clock</string>
- <key>parameters</key>
- <array/>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns CPU time used by the program in seconds</string>
- </map>
- <map>
- <key>name</key>
- <string>date</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>format</string>
- <key>type</key>
- <string>string</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>time</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string | OsDateTime | nil</string>
- <key>comment</key>
- <string>Returns a string or table containing date and time</string>
- </map>
- <map>
- <key>name</key>
- <string>difftime</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t2</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>t1</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the difference in seconds between two times</string>
- </map>
- <map>
- <key>name</key>
- <string>time</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>time</string>
- <key>type</key>
- <string>OsDateTime</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number?</string>
- <key>comment</key>
- <string>Returns the current time or converts a table to time</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>string</string>
- <key>comment</key>
- <string>String manipulation library</string>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>byte</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>i</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>j</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>...number</string>
- <key>comment</key>
- <string>Returns the internal numeric codes of the characters</string>
- </map>
- <map>
- <key>name</key>
- <string>char</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>number</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Returns a string from character codes</string>
- </map>
- <map>
- <key>name</key>
- <string>find</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>pattern</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>init</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>plain</string>
- <key>type</key>
- <string>boolean</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>(number?, number?, ...string)</string>
- <key>comment</key>
- <string>Finds first match of pattern in string</string>
- </map>
- <map>
- <key>name</key>
- <string>format</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>formatstring</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>type</key>
- <string>any</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Returns a formatted string</string>
- </map>
- <map>
- <key>name</key>
- <string>gmatch</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>pattern</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>() -&gt; ...string</string>
- <key>comment</key>
- <string>Returns an iterator function for pattern matches</string>
- </map>
- <map>
- <key>name</key>
- <string>gsub</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>pattern</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>repl</string>
- <key>type</key>
- <string>string | { [string]: string } | (...string) -&gt; string</string>
- </map>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>(string, number)</string>
- <key>comment</key>
- <string>Global substitution of pattern matches</string>
- </map>
- <map>
- <key>name</key>
- <string>len</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the length of the string</string>
- </map>
- <map>
- <key>name</key>
- <string>lower</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Converts string to lowercase</string>
- </map>
- <map>
- <key>name</key>
- <string>match</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>pattern</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>init</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>...string</string>
- <key>comment</key>
- <string>Returns captures from pattern match</string>
- </map>
- <map>
- <key>name</key>
- <string>pack</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>fmt</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>type</key>
- <string>any</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Packs values into a binary string</string>
- </map>
- <map>
- <key>name</key>
- <string>packsize</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>fmt</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the size of a packed string for the given format</string>
- </map>
- <map>
- <key>name</key>
- <string>rep</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Returns a string repeated n times</string>
- </map>
- <map>
- <key>name</key>
- <string>reverse</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Reverses a string</string>
- </map>
- <map>
- <key>name</key>
- <string>split</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>separator</string>
- <key>type</key>
- <string>string</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>{string}</string>
- <key>comment</key>
- <string>Splits a string by separator</string>
- </map>
- <map>
- <key>name</key>
- <string>sub</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>i</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>j</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Returns a substring</string>
- </map>
- <map>
- <key>name</key>
- <string>unpack</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>fmt</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>pos</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>...any</string>
- <key>comment</key>
- <string>Unpacks values from a binary string</string>
- </map>
- <map>
- <key>name</key>
- <string>upper</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Converts string to uppercase</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>table</string>
- <key>comment</key>
- <string>Table manipulation library</string>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>concat</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>list</string>
- <key>type</key>
- <string>{string}</string>
- </map>
- <map>
- <key>name</key>
- <string>sep</string>
- <key>type</key>
- <string>string</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>i</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>j</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Concatenates table elements into a string</string>
- </map>
- <map>
- <key>name</key>
- <string>foreach</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{[any]: any}</string>
- </map>
- <map>
- <key>name</key>
- <string>f</string>
- <key>type</key>
- <string>(key: any, value: any) -&gt; any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>any?</string>
- <key>comment</key>
- <string>Iterates over table key-value pairs (deprecated)</string>
- </map>
- <map>
- <key>name</key>
- <string>foreachi</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- <map>
- <key>name</key>
- <string>f</string>
- <key>type</key>
- <string>(index: number, value: any) -&gt; any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>any?</string>
- <key>comment</key>
- <string>Iterates over array indices (deprecated)</string>
- </map>
- <map>
- <key>name</key>
- <string>getn</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the length of a table (deprecated, use # operator)</string>
- </map>
- <map>
- <key>name</key>
- <string>maxn</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- </array>
- <key>returnType</key>
- <string>number</string>
- <key>comment</key>
- <string>Returns the largest positive numeric index</string>
- </map>
- <map>
- <key>name</key>
- <string>insert</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>list</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Inserts an element at the end of a list</string>
- <key>overloads</key>
- <array>
- <map>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>list</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- <map>
- <key>name</key>
- <string>pos</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Inserts an element at a specific position</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>remove</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>list</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- <map>
- <key>name</key>
- <string>pos</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>any?</string>
- <key>comment</key>
- <string>Removes and returns an element from a list</string>
- </map>
- <map>
- <key>name</key>
- <string>sort</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>list</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- <map>
- <key>name</key>
- <string>comp</string>
- <key>type</key>
- <string>(a: any, b: any) -&gt; boolean</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Sorts list elements in place</string>
- </map>
- <map>
- <key>name</key>
- <string>pack</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>any</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>{ n: number, [number]: any }</string>
- <key>comment</key>
- <string>Packs arguments into a table with length field n</string>
- </map>
- <map>
- <key>name</key>
- <string>unpack</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>list</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- <map>
- <key>name</key>
- <string>i</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>j</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>...any</string>
- <key>comment</key>
- <string>Unpacks table elements as multiple return values</string>
- </map>
- <map>
- <key>name</key>
- <string>move</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>a1</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- <map>
- <key>name</key>
- <string>f</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>e</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>a2</string>
- <key>type</key>
- <string>{any}</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>{any}</string>
- <key>comment</key>
- <string>Moves elements from one table to another</string>
- </map>
- <map>
- <key>name</key>
- <string>create</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>count</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>any</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>{any}</string>
- <key>comment</key>
- <string>Creates a new table with pre-allocated array slots</string>
- </map>
- <map>
- <key>name</key>
- <string>find</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{any}</string>
- </map>
- <map>
- <key>name</key>
- <string>value</string>
- <key>type</key>
- <string>any</string>
- </map>
- <map>
- <key>name</key>
- <string>init</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number?</string>
- <key>comment</key>
- <string>Finds the index of a value in an array</string>
- </map>
- <map>
- <key>name</key>
- <string>clear</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{[any]: any}</string>
- </map>
- </array>
- <key>returnType</key>
- <string>()</string>
- <key>comment</key>
- <string>Removes all elements from a table</string>
- </map>
- <map>
- <key>name</key>
- <string>freeze</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{[any]: any}</string>
- </map>
- </array>
- <key>returnType</key>
- <string>{[any]: any}</string>
- <key>comment</key>
- <string>Makes a table read-only</string>
- </map>
- <map>
- <key>name</key>
- <string>isfrozen</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{[any]: any}</string>
- </map>
- </array>
- <key>returnType</key>
- <string>boolean</string>
- <key>comment</key>
- <string>Returns true if a table is frozen</string>
- </map>
- <map>
- <key>name</key>
- <string>clone</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>t</string>
- <key>type</key>
- <string>{[any]: any}</string>
- </map>
- </array>
- <key>returnType</key>
- <string>{[any]: any}</string>
- <key>comment</key>
- <string>Creates a shallow copy of a table</string>
- </map>
- </array>
- </map>
- <map>
- <key>name</key>
- <string>utf8</string>
- <key>comment</key>
- <string>UTF-8 support library</string>
- <key>properties</key>
- <array>
- <map>
- <key>name</key>
- <string>charpattern</string>
- <key>type</key>
- <string>string</string>
- <key>comment</key>
- <string>Pattern that matches exactly one UTF-8 byte sequence</string>
- </map>
- </array>
- <key>functions</key>
- <array>
- <map>
- <key>name</key>
- <string>char</string>
- <key>parameters</key>
- <array>
- <map>
- <key>type</key>
- <string>number</string>
- <key>variadic</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>string</string>
- <key>comment</key>
- <string>Returns a string from UTF-8 codepoints</string>
- </map>
- <map>
- <key>name</key>
- <string>codes</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- </array>
- <key>returnType</key>
- <string>((string, number) -&gt; (number, number), string, number)</string>
- <key>comment</key>
- <string>Returns an iterator for UTF-8 codepoints in a string</string>
- </map>
- <map>
- <key>name</key>
- <string>codepoint</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>i</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>j</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>...number</string>
- <key>comment</key>
- <string>Returns the codepoints of characters in a string</string>
- </map>
- <map>
- <key>name</key>
- <string>len</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>i</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- <map>
- <key>name</key>
- <string>j</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>(number?, number?)</string>
- <key>comment</key>
- <string>Returns the number of UTF-8 characters in a string, or nil and error position</string>
- </map>
- <map>
- <key>name</key>
- <string>offset</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>s</string>
- <key>type</key>
- <string>string</string>
- </map>
- <map>
- <key>name</key>
- <string>n</string>
- <key>type</key>
- <string>number</string>
- </map>
- <map>
- <key>name</key>
- <string>i</string>
- <key>type</key>
- <string>number</string>
- <key>optional</key>
- <boolean>true</boolean>
- </map>
- </array>
- <key>returnType</key>
- <string>number?</string>
- <key>comment</key>
- <string>Returns the byte position of the n-th character</string>
- </map>
- </array>
- </map>
- </array>
- <key>globalFunctions</key>
- <array>
- <map>
- <key>name</key>
- <string>dangerouslyexecuterequiredmodule</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>f</string>
- <key>type</key>
- <string>(...any) -&gt; ...any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>...any</string>
- <key>comment</key>
- <string>Dangerously executes a required module function</string>
- </map>
- <map>
- <key>name</key>
- <string>touuid</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>val</string>
- <key>type</key>
- <string>string | buffer | uuid</string>
- </map>
- </array>
- <key>returnType</key>
- <string>uuid?</string>
- <key>comment</key>
- <string>Converts a string, buffer, or uuid to a uuid, returns nil if invalid</string>
- </map>
- <map>
- <key>name</key>
- <string>tovector</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>val</string>
- <key>type</key>
- <string>any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>vector?</string>
- <key>comment</key>
- <string>Converts a value to a vector, returns nil if invalid</string>
- </map>
- <map>
- <key>name</key>
- <string>toquaternion</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>val</string>
- <key>type</key>
- <string>any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion?</string>
- <key>comment</key>
- <string>Converts a value to a quaternion, returns nil if invalid</string>
- </map>
- <map>
- <key>name</key>
- <string>torotation</string>
- <key>parameters</key>
- <array>
- <map>
- <key>name</key>
- <string>val</string>
- <key>type</key>
- <string>any</string>
- </map>
- </array>
- <key>returnType</key>
- <string>quaternion?</string>
- <key>comment</key>
- <string>Converts a value to a rotation (quaternion), returns nil if invalid</string>
- </map>
- </array>
- <key>constants</key>
- <array/>
-</map>
-</llsd>
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index a9e3afbc58..544473ba77 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -507,11 +507,10 @@ bool LLScriptEdCore::postBuild()
initMenu();
- mSyntaxIDConnection = LLSyntaxIdLSL::getInstance()->addSyntaxIDCallback(boost::bind(&LLScriptEdCore::processKeywords, this));
+ mSyntaxIDConnection = LLSyntaxDefCache::getInstance()->addSyntaxIDCallback(boost::bind(&LLScriptEdCore::processKeywords, this));
// Intialise keyword highlighting for the current simulator's version of LSL
- LLSyntaxIdLSL::getInstance()->initialize();
- LLSyntaxLua::getInstance()->initialize();
+ LLSyntaxDefCache::getInstance();
processKeywords();
mCommitCallbackRegistrar.add("FontSize.Set", boost::bind(&LLScriptEdCore::onChangeFontSize, this, _2));
diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp
index 2a4c2b9d0b..ac6b81f677 100644
--- a/indra/newview/llscripteditor.cpp
+++ b/indra/newview/llscripteditor.cpp
@@ -342,8 +342,8 @@ void LLScriptEditor::drawLineNumbers()
void LLScriptEditor::initKeywords(bool luau_language)
{
- mKeywordsLua.initialize(LLSyntaxLua::getInstance()->getKeywordsXML(), true);
- mKeywordsLSL.initialize(LLSyntaxIdLSL::getInstance()->getKeywordsXML(), false);
+ mKeywordsLua.initialize(LLSyntaxDefCache::getInstance()->getLuaKeywords(), true);
+ mKeywordsLSL.initialize(LLSyntaxDefCache::getInstance()->getLSLKeywords(), false);
mLuauLanguage = luau_language;
diff --git a/indra/newview/llscripteditorws.cpp b/indra/newview/llscripteditorws.cpp
index 30a1ca53f6..3ca9be44bc 100644
--- a/indra/newview/llscripteditorws.cpp
+++ b/indra/newview/llscripteditorws.cpp
@@ -2,6 +2,9 @@
* @file llscripteditorws.cpp
* @brief JSON-RPC 2.0 WebSocket server implementation for external script editor integration
*
+ * For a full description of the JSON-RPC protocol and all supported methods,
+ * see doc/external-editor-json-rpc.md in the repository root.
+ *
* $LicenseInfo:firstyear=2025&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2025, Linden Research, Inc.
@@ -73,7 +76,7 @@ LLWebsocketMgr::WSConnection::ptr_t LLScriptEditorWSServer::connectionFactory(LL
void LLScriptEditorWSServer::onStarted()
{
- LLSyntaxIdLSL& syntax_id_mgr = LLSyntaxIdLSL::instance();
+ LLSyntaxDefCache& syntax_id_mgr = LLSyntaxDefCache::instance();
wptr_t that(std::static_pointer_cast<LLScriptEditorWSServer>(shared_from_this()));
mLastSyntaxId = syntax_id_mgr.getSyntaxID();
@@ -272,6 +275,26 @@ void LLScriptEditorWSServer::setupConnectionMethods(LLJSONRPCConnection::ptr_t c
}
return LLSD();
});
+ script_connection->registerMethod("language.syntax.cache",
+ [that](const std::string&, const LLSD&, const LLSD& params)
+ {
+ auto server = that.lock();
+ if (server)
+ {
+ return server->handleSyntaxCacheRequest();
+ }
+ return LLSD();
+ });
+ script_connection->registerMethod("language.syntax.get",
+ [that](const std::string&, const LLSD&, const LLSD& params)
+ {
+ auto server = that.lock();
+ if (server)
+ {
+ return server->handleSyntaxCacheFileRequest(params);
+ }
+ return LLSD();
+ });
script_connection->registerMethod("script.subscribe",
[that, connection_id](const std::string&, const LLSD&, const LLSD& params) -> LLSD
{
@@ -302,7 +325,7 @@ void LLScriptEditorWSServer::setupConnectionMethods(LLJSONRPCConnection::ptr_t c
void LLScriptEditorWSServer::broadcastLanguageChange()
{
- LLUUID syntax_id = LLSyntaxIdLSL::instance().getSyntaxID();
+ LLUUID syntax_id = LLSyntaxDefCache::instance().getSyntaxID();
if (syntax_id != mLastSyntaxId)
{
@@ -340,12 +363,12 @@ LLSD LLScriptEditorWSServer::handleSyntaxRequest(const LLSD& params) const
response["id"] = mLastSyntaxId;
if (category == "defs.lua")
{
- response["defs"] = LLSyntaxLua::instance().getTypesXML();
+ response["defs"] = LLSyntaxDefCache::instance().getLuaKeywords();
response["success"] = response["defs"].isDefined();
}
else if (category == "defs.lsl")
{
- response["defs"] = LLSyntaxIdLSL::instance().getKeywordsXML();
+ response["defs"] = LLSyntaxDefCache::instance().getLSLKeywords();
response["success"] = response["defs"].isDefined();
}
else
@@ -356,6 +379,71 @@ LLSD LLScriptEditorWSServer::handleSyntaxRequest(const LLSD& params) const
return response;
}
+LLSD LLScriptEditorWSServer::handleSyntaxCacheRequest() const
+{
+ LLSD response;
+ // Add array of cached syntax definition files
+ LLSD syntax_files = LLSD::emptyArray();
+ for (const auto& name : LLSyntaxDefCache::instance().getCacheFileNames())
+ {
+ syntax_files.append(name);
+ }
+ response["files"] = syntax_files;
+ response["success"] = true;
+ return response;
+}
+
+LLSD LLScriptEditorWSServer::handleSyntaxCacheFileRequest(const LLSD& params) const
+{
+ std::string filename = params["filename"].asString();
+ bool as_json = params["as_json"].asBoolean();
+
+ LLSyntaxDefCache& cache = LLSyntaxDefCache::instance();
+ LLSD response;
+
+ if (filename.empty())
+ {
+ response["error"] = "No filename specified";
+ response["success"] = false;
+ return response;
+ }
+ if (!cache.hasCacheFile(filename))
+ {
+ response["error"] = "Requested syntax cache file not found";
+ response["success"] = false;
+ return response;
+ }
+ bool success = false;
+ if (as_json)
+ {
+ LLSD file_content = cache.loadCacheFileAsLLSD(filename);
+ if (file_content.isDefined())
+ {
+ response["content"] = file_content;
+ success = true;
+ }
+ else
+ {
+ response["error"] = "Failed to load and format syntax cache file.";
+ }
+ }
+ else
+ {
+ std::string content = cache.loadCacheFile(filename);
+ if (!content.empty())
+ {
+ response["content"] = content;
+ success = true;
+ }
+ else
+ {
+ response["error"] = "Failed to load syntax cache file";
+ }
+ }
+ response["success"] = success;
+ return response;
+}
+
LLSD LLScriptEditorWSServer::handleScriptSubscribe(U32 connection_id, const LLSD& params)
{
LLSD response(LLSD::emptyMap());
@@ -710,12 +798,13 @@ void LLScriptEditorWSConnection::onOpen()
languages.append("lsl");
languages.append("luau");
handshake["languages"] = languages;
- handshake["syntax_id"] = LLSyntaxIdLSL::instance().getSyntaxID();
+ handshake["syntax_id"] = LLSyntaxDefCache::instance().getSyntaxID();
// Features object
LLSD features;
features["live_sync"] = true;
features["compilation"] = true;
+ features["syntax_cache"] = true;
handshake["features"] = features;
wptr_t that = shared_from_this();
diff --git a/indra/newview/llscripteditorws.h b/indra/newview/llscripteditorws.h
index c8898c66a7..765ebe83f2 100644
--- a/indra/newview/llscripteditorws.h
+++ b/indra/newview/llscripteditorws.h
@@ -192,6 +192,8 @@ protected:
LLSD handleLanguageIdRequest() const;
LLSD handleSyntaxRequest(const LLSD &params) const;
+ LLSD handleSyntaxCacheRequest() const;
+ LLSD handleSyntaxCacheFileRequest(const LLSD& params) const;
LLSD handleScriptSubscribe(U32 connection_id, const LLSD& params);
LLSD handleScriptUnsubscribe(U32 connection_id, const LLSD& params);
LLSD handleFileWatcherFileListRequest() const;
diff --git a/indra/newview/llsyntaxid.cpp b/indra/newview/llsyntaxid.cpp
index 16274f59bc..9c1a0ef403 100644
--- a/indra/newview/llsyntaxid.cpp
+++ b/indra/newview/llsyntaxid.cpp
@@ -35,40 +35,57 @@
#include "llviewerregion.h"
#include "llcorehttputil.h"
+
//-----------------------------------------------------------------------------
// LLSyntaxIdLSL
//-----------------------------------------------------------------------------
-const std::string SYNTAX_ID_CAPABILITY_NAME = "LSLSyntax";
-const std::string SYNTAX_ID_SIMULATOR_FEATURE = "LSLSyntaxId";
-const std::string FILENAME_DEFAULT_LSL = "keywords_lsl_default.xml";
-const std::string FILENAME_DEFAULT_LUA = "keywords_lua_default.xml";
+namespace
+{
+ const std::string SYNTAX_ID_CAPABILITY_NAME = "LSLSyntax";
+ const std::string SYNTAX_DEF_CAPABILITY_NAME = "ScriptDefinitions";
+ const std::string SYNTAX_ID_SIMULATOR_FEATURE = "LSLSyntaxId";
+ const std::string FILENAME_INTERNAL_LSL = "lsl_keywords.xml";
+ const std::string FILENAME_INTERNAL_LUA = "lua_keywords.xml";
-/**
- * @brief LLSyntaxIdLSL constructor
- */
-LLSyntaxIdLSL::LLSyntaxIdLSL()
-: mKeywordsXml(LLSD())
-, mCapabilityURL(std::string())
-, mFilePath(LL_PATH_APP_SETTINGS)
-, mSyntaxId(LLUUID())
-, mInitialized(false)
+ constexpr U32 LLSD_SYNTAX_LSL_VERSION_EXPECTED = 2;
+ const std::string LLSD_SYNTAX_LSL_VERSION_KEY("llsd-lsl-syntax-version");
+
+ const std::unordered_set<std::string> MEMCACHED_LLSD = {
+ FILENAME_INTERNAL_LSL,
+ FILENAME_INTERNAL_LUA
+ };
+} // namespace
+
+//========================================================================
+void LLSyntaxDefCache::initSingleton()
{
- loadDefaultKeywordsIntoLLSD();
- mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLSyntaxIdLSL::handleRegionChanged, this));
+ buildDefaultCache();
+ loadKeywordsIntoLLSD();
+ mRegionChangedCallback = gAgent.addRegionChangedCallback(boost::bind(&LLSyntaxDefCache::handleRegionChanged, this));
handleRegionChanged(); // Kick off an initial caps query and fetch
}
-void LLSyntaxIdLSL::buildFullFileSpec()
+void LLSyntaxDefCache::cleanupSingleton()
{
- ELLPath path = mSyntaxId.isNull() ? LL_PATH_APP_SETTINGS : LL_PATH_CACHE;
- const std::string filename = mSyntaxId.isNull() ? FILENAME_DEFAULT_LSL : "keywords_lsl_" + mSyntaxId.asString() + ".llsd.xml";
- mFullFileSpec = gDirUtilp->getExpandedFilename(path, filename);
+ gAgent.removeRegionChangedCallback(mRegionChangedCallback);
+ mLSLKeywords = LLSD();
+ mLuaKeywords = LLSD();
+ mCapabilityURL = std::string();
+ mSyntaxId = LLUUID();
+ mFileCachePaths.clear();
}
-//-----------------------------------------------------------------------------
-// syntaxIdChange()
-//-----------------------------------------------------------------------------
-bool LLSyntaxIdLSL::syntaxIdChanged()
+boost::signals2::connection LLSyntaxDefCache::addSyntaxIDCallback(const syntax_id_changed_signal_t::slot_type& cb)
+{
+ return mSyntaxIDChangedSignal.connect(cb);
+}
+
+//========================================================================
+// checkSyntaxId()
+// Checks the current region for the LSLSyntaxId feature and capability, and
+// if found checks the syntax ID against the one we have. If they differ,
+// updates the syntax ID and returns true. Otherwise returns false.
+bool LLSyntaxDefCache::updateSyntaxId()
{
LLViewerRegion* region = gAgent.getRegion();
@@ -83,51 +100,97 @@ bool LLSyntaxIdLSL::syntaxIdChanged()
{
// get and check the hash
LLUUID new_syntax_id = sim_features[SYNTAX_ID_SIMULATOR_FEATURE].asUUID();
- mCapabilityURL = region->getCapability(SYNTAX_ID_CAPABILITY_NAME);
+
+ // *Note* the syntax ID may not have changed, but the region almost certainly has.
+ // update the cap URL
+ mCapabilityURL = region->getCapability(SYNTAX_DEF_CAPABILITY_NAME);
+ mUseDefsCap = !mCapabilityURL.empty();
+ if (!mUseDefsCap)
+ {
+ mCapabilityURL = region->getCapability(SYNTAX_ID_CAPABILITY_NAME);
+ }
LL_DEBUGS("SyntaxLSL") << SYNTAX_ID_SIMULATOR_FEATURE << " capability URL: " << mCapabilityURL << LL_ENDL;
+
if (new_syntax_id != mSyntaxId)
{
LL_DEBUGS("SyntaxLSL") << "New SyntaxID '" << new_syntax_id << "' found." << LL_ENDL;
mSyntaxId = new_syntax_id;
return true;
}
- else
- LL_DEBUGS("SyntaxLSL") << "SyntaxID matches what we have." << LL_ENDL;
+
+ LL_DEBUGS("SyntaxLSL") << "SyntaxID has not changed. Still " << mSyntaxId << LL_ENDL;
}
}
else
{
- region->setCapabilitiesReceivedCallback(boost::bind(&LLSyntaxIdLSL::handleCapsReceived, this, _1));
+ region->setCapabilitiesReceivedCallback(boost::bind(&LLSyntaxDefCache::handleCapsReceived, this, _1));
LL_DEBUGS("SyntaxLSL") << "Region has not received capabilities. Waiting for caps..." << LL_ENDL;
}
}
return false;
}
+void LLSyntaxDefCache::handleRegionChanged()
+{
+ if (updateSyntaxId())
+ {
+ if (!checkCacheAndLoad(mSyntaxId))
+ {
+ fetchKeywords();
+ }
+ }
+}
+
+void LLSyntaxDefCache::handleCapsReceived(const LLUUID& region_uuid)
+{
+ LLViewerRegion* current_region = gAgent.getRegion();
+
+ if (region_uuid.notNull() && current_region->getRegionID() == region_uuid)
+ {
+ updateSyntaxId();
+ if (!checkCacheAndLoad(mSyntaxId))
+ {
+ fetchKeywords();
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
-// fetchKeywordsFile
-//-----------------------------------------------------------------------------
-void LLSyntaxIdLSL::fetchKeywordsFile(const std::string& filespec)
+// fetchKeywords
+// Initiates a fetch of the current language definitions from the region caps.
+void LLSyntaxDefCache::fetchKeywords()
{
- LLCoros::instance().launch("LLSyntaxIdLSL::fetchKeywordsFileCoro",
- boost::bind(&LLSyntaxIdLSL::fetchKeywordsFileCoro, this, mCapabilityURL, filespec));
- LL_DEBUGS("SyntaxLSL") << "LSLSyntaxId capability URL is: " << mCapabilityURL << ". Filename to use is: '" << filespec << "'." << LL_ENDL;
+ if (mCapabilityURL.empty())
+ {
+ LL_WARNS("SyntaxLSL") << "No capability URL for fetching syntax definitions." << LL_ENDL;
+ return;
+ }
+ if (mUseDefsCap)
+ {
+ LLCoros::instance().launch("LLSyntaxDefCache::fetchKeywordsDefsCoro",
+ boost::bind(&LLSyntaxDefCache::fetchKeywordsDefsCoro, this, mCapabilityURL, mSyntaxId));
+ }
+ else
+ {
+ LLCoros::instance().launch("LLSyntaxDefCache::fetchKeywordsFileCoro",
+ boost::bind(&LLSyntaxDefCache::fetchKeywordsFileCoro, this, mCapabilityURL, mSyntaxId));
+ }
}
//-----------------------------------------------------------------------------
// fetchKeywordsFileCoro
-//-----------------------------------------------------------------------------
-void LLSyntaxIdLSL::fetchKeywordsFileCoro(std::string url, std::string fileSpec)
+// This uses the legacy language cap which only sends the LSL keywords file.
+void LLSyntaxDefCache::fetchKeywordsFileCoro(std::string url, LLUUID syntax_id)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter = std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("fetchKeywordsFileCoro", httpPolicy);
LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>();
- std::pair<std::set<std::string>::iterator, bool> insrt = mInflightFetches.insert(fileSpec);
+ auto insrt = mInflightFetches.insert(syntax_id);
if (!insrt.second)
{
- LL_WARNS("SyntaxLSL") << "Already downloading keyword file called \"" << fileSpec << "\"." << LL_ENDL;
+ LL_WARNS("SyntaxLSL") << "Already downloading keyword file for syntax ID \"" << syntax_id << "\"." << LL_ENDL;
return;
}
@@ -136,11 +199,11 @@ void LLSyntaxIdLSL::fetchKeywordsFileCoro(std::string url, std::string fileSpec)
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- mInflightFetches.erase(fileSpec);
+ mInflightFetches.erase(syntax_id);
if (!status)
{
- LL_WARNS("SyntaxLSL") << "Failed to fetch syntax file \"" << fileSpec << "\"" << LL_ENDL;
+ LL_WARNS("SyntaxLSL") << "Failed to fetch syntax file for syntax ID \"" << syntax_id << "\"" << LL_ENDL;
return;
}
@@ -148,13 +211,38 @@ void LLSyntaxIdLSL::fetchKeywordsFileCoro(std::string url, std::string fileSpec)
if (isSupportedVersion(result))
{
- // Shuttle this task to the main coro/worker.
- // loadKeywordsIntoLLSD will attempt to get a mutex which is not coro aware.
- LLAppViewer::instance()->postToMainCoro([this, result, fileSpec]()
+ std::string path = buildCacheDirectoryName(syntax_id);
+
+ if (!LLFile::exists(path))
+ {
+ LL_DEBUGS("SyntaxLSL") << "Cache directory '" << path << "' does not exist. Attempting to create." << LL_ENDL;
+ if (LLFile::mkdir(path))
{
- setKeywordsXml(result);
- cacheFile(fileSpec, result);
- loadKeywordsIntoLLSD();
+ LL_WARNS("SyntaxLSL") << "Failed to create cache directory '" << path << "'. Cannot cache syntax defs file." << LL_ENDL;
+ return;
+ }
+ }
+
+ // Note that after this call the file cache will have all well known files pointing
+ // to the default versions, so below, where we get the path to the lua keywords
+ // well be loading the default version.
+ buildDefaultCache();
+
+ // The LSL keywords we just received
+ std::string full_path = gDirUtilp->add(path, FILENAME_INTERNAL_LSL);
+ if (writeCacheFile(full_path, result))
+ {
+ mFileCachePaths.addNamePath(FILENAME_INTERNAL_LSL, full_path);
+ }
+ // We need to manually load the Lua keywords
+ full_path = mFileCachePaths.getPath(FILENAME_INTERNAL_LUA);
+ LLSD lua_defs = loadDeserializedCacheFile(full_path);
+
+ setKeywords(result, lua_defs);
+
+ // Shuttle this task to the main coro/worker.
+ LLAppViewer::instance()->postToMainCoro([this]() {
+ mSyntaxIDChangedSignal();
});
}
else
@@ -164,73 +252,198 @@ void LLSyntaxIdLSL::fetchKeywordsFileCoro(std::string url, std::string fileSpec)
}
-//-----------------------------------------------------------------------------
-// cacheFile
-//-----------------------------------------------------------------------------
-void LLSyntaxIdLSL::cacheFile(const std::string &fileSpec, const LLSD& content_ref)
+void LLSyntaxDefCache::fetchKeywordsDefsCoro(std::string url, LLUUID syntax_id)
{
- std::stringstream str;
- LLSDSerialize::toXML(content_ref, str);
- const std::string xml = str.str();
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter =
+ std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>("fetchKeywordsDefsCoro", httpPolicy);
+ LLCore::HttpRequest::ptr_t httpRequest = std::make_shared<LLCore::HttpRequest>();
- // save the str to disk, usually to the cache.
- llofstream file(fileSpec.c_str(), std::ios_base::out);
- file.write(xml.c_str(), str.str().size());
- file.close();
+ static std::set<LLUUID> inflightDefsFetches;
+ auto insrt = inflightDefsFetches.insert(syntax_id);
+ //auto insrt = mInflightFetches.insert(syntax_id);
+ if (!insrt.second)
+ {
+ LL_WARNS("SyntaxLSL") << "Already downloading keyword defs for \"" << syntax_id << "\"." << LL_ENDL;
+ return;
+ }
- LL_DEBUGS("SyntaxLSL") << "Syntax file received, saving as: '" << fileSpec << "'" << LL_ENDL;
-}
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
-//-----------------------------------------------------------------------------
-// initialize
-//-----------------------------------------------------------------------------
-void LLSyntaxIdLSL::initialize()
-{
- if(mInitialized) return;
- if (mSyntaxId.isNull())
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ inflightDefsFetches.erase(syntax_id);
+
+ if (!status)
{
- loadDefaultKeywordsIntoLLSD();
+ LL_WARNS("SyntaxLSL") << "Failed to fetch syntax file \"" << syntax_id << "\"" << LL_ENDL;
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+ return;
}
- else if (!mCapabilityURL.empty())
+
+ // Now we need to walk through the returned LLSD. It consists of a map keyed on the file name containing a binary
+ // blob of the actual file contents.
+ LLSD files = result["files"];
+ LLSD memcached_keywords;
+ if (files.isMap())
{
- LL_DEBUGS("SyntaxLSL") << "LSL version has changed, getting appropriate file." << LL_ENDL;
+ std::string path = buildCacheDirectoryName(syntax_id);
- // Need a full spec regardless of file source, so build it now.
- buildFullFileSpec();
- if (mSyntaxId.notNull())
+ if (!LLFile::exists(path))
{
- if (!gDirUtilp->fileExists(mFullFileSpec))
- { // Does not exist, so fetch it from the capability
- LL_DEBUGS("SyntaxLSL") << "LSL syntax not cached, attempting download." << LL_ENDL;
- fetchKeywordsFile(mFullFileSpec);
- }
- else
+ LL_DEBUGS("SyntaxLSL") << "Cache directory '" << path << "' does not exist. Attempting to create." << LL_ENDL;
+ if (LLFile::mkdir(path))
{
- LL_DEBUGS("SyntaxLSL") << "Found cached Syntax file: " << mFullFileSpec << " Loading keywords." << LL_ENDL;
- loadKeywordsIntoLLSD();
+ LL_WARNS("SyntaxLSL") << "Failed to create cache directory '" << path << "'. Cannot cache syntax defs file." << LL_ENDL;
+ return;
}
}
- else
+
+ buildDefaultCache();
+
+ for (const auto &[filename, contents] : llsd::inMap(files))
{
- LL_DEBUGS("SyntaxLSL") << "LSLSyntaxId is null. Loading default values" << LL_ENDL;
- loadDefaultKeywordsIntoLLSD();
+ std::string full_path = gDirUtilp->add(path, filename);
+
+ if (MEMCACHED_LLSD.find(filename) != MEMCACHED_LLSD.end())
+ { // Maintain some keyword LLSDs internally, LSL and Lua
+ memcached_keywords[filename] = contents;
+ }
+
+ if (writeCacheFile(full_path, contents))
+ {
+ mFileCachePaths.addNamePath(filename, full_path);
+ }
}
}
else
{
- LL_DEBUGS("SyntaxLSL") << "LSLSyntaxId capability URL is empty." << LL_ENDL;
- loadDefaultKeywordsIntoLLSD();
+ LL_WARNS("SyntaxLSL") << "Malformed syntax defs response, missing 'files' map." << LL_ENDL;
}
- mInitialized = true;
+
+ result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+
+ setKeywords(memcached_keywords[FILENAME_INTERNAL_LSL], memcached_keywords[FILENAME_INTERNAL_LUA]);
+ LLAppViewer::instance()->postToMainCoro(
+ [this]()
+ {
+ mSyntaxIDChangedSignal();
+ });
}
//-----------------------------------------------------------------------------
+// buildCache
+// Constructs the cache file paths for the given syntax ID. If the syntax ID is null,
+// constructs the default cache file paths.
+void LLSyntaxDefCache::buildCachePaths(const LLUUID &syntax_id)
+{
+ if (syntax_id.notNull())
+ { // Initialize the cache files to point to the default files
+ buildCachePaths(LLUUID::null);
+ }
+ else
+ {
+ mFileCachePaths.clear();
+ }
+
+ std::string cache_dir = buildCacheDirectoryName(syntax_id);
+ if (!LLFile::exists(cache_dir))
+ {
+ LL_DEBUGS("SyntaxLSL") << "Cache directory '" << cache_dir << "' does not exist." << LL_ENDL;
+ return;
+ }
+
+ auto files = gDirUtilp->getFilesInDir(cache_dir);
+ for (const auto &file : files)
+ {
+ mFileCachePaths.addNamePath(file, gDirUtilp->add(cache_dir, file));
+ }
+}
+
+bool LLSyntaxDefCache::writeCacheFile(const std::string &fileSpec, const LLSD& content_ref)
+{
+ bool binary(content_ref.isBinary());
+ std::ios_base::openmode mode(binary ? (std::ios_base::out | std::ios_base::binary)
+ : std::ios_base::out);
+ std::ofstream file(fileSpec.c_str(), mode);
+
+ if (!file.is_open())
+ {
+ LL_WARNS("SyntaxLSL") << "Failed to open file for writing: '" << fileSpec << "'" << LL_ENDL;
+ return false;
+ }
+
+ if (binary)
+ {
+ LL_DEBUGS("SyntaxLSL") << "Caching raw content to '" << fileSpec << "'" << LL_ENDL;
+ file.write((const char*)content_ref.asBinary().data(), content_ref.asBinary().size());
+ }
+ else
+ {
+ LL_DEBUGS("SyntaxLSL") << "Caching XML content to '" << fileSpec << "'" << LL_ENDL;
+ LLSDSerialize::serialize(content_ref, file, LLSDSerialize::LLSD_XML, LLSDFormatter::OPTIONS_PRETTY);
+ }
+ file.close();
+
+ if (!file.good())
+ {
+ LL_WARNS("SyntaxLSL") << "Failed to write content to file: '" << fileSpec << "'" << LL_ENDL;
+ return false;
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// checkCacheAndLoad
+// Tests the local cache for the given syntax ID. If found it loads the keywords
+// from the cache into LLSD and returns true. Otherwise returns false.
+bool LLSyntaxDefCache::checkCacheAndLoad(const LLUUID& syntax_id)
+{
+ if (checkLocalCache(syntax_id))
+ {
+ buildCachePaths(syntax_id);
+ loadKeywordsIntoLLSD();
+ return true;
+ }
+ return false;
+}
+
+std::string LLSyntaxDefCache::buildCacheDirectoryName(const LLUUID& syntax_id)
+{
+ if (syntax_id.isNull())
+ {
+ LL_DEBUGS("SyntaxLSL") << "No SyntaxID, using app settings directory." << LL_ENDL;
+ return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "syntax_default");
+ }
+ else
+ {
+ LL_DEBUGS("SyntaxLSL") << "Using cache directory for SyntaxID '" << syntax_id << "'." << LL_ENDL;
+ std::string cache_dir_name = "syntax_" + syntax_id.asString();
+
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
+ }
+}
+
+bool LLSyntaxDefCache::checkLocalCache(const LLUUID& syntax_id) const
+{
+ if (syntax_id.isNull())
+ { // Cache check will always fail if we don't have a valid SyntaxID, so skip it in that case.
+ LL_DEBUGS("SyntaxLSL") << "No SyntaxID, skipping local cache check." << LL_ENDL;
+ return false;
+ }
+
+ // Check for the existence of the cache directory for this syntax ID. If it doesn't exist, then we don't have a cached file.
+ std::string cache_dir = buildCacheDirectoryName(syntax_id);
+ return gDirUtilp->fileExists(cache_dir);
+}
+
+
+//-----------------------------------------------------------------------------
// isSupportedVersion
//-----------------------------------------------------------------------------
-const U32 LLSD_SYNTAX_LSL_VERSION_EXPECTED = 2;
-const std::string LLSD_SYNTAX_LSL_VERSION_KEY("llsd-lsl-syntax-version");
-bool LLSyntaxIdLSL::isSupportedVersion(const LLSD& content)
+bool LLSyntaxDefCache::isSupportedVersion(const LLSD& content)
{
bool is_valid = false;
/*
@@ -256,128 +469,100 @@ bool LLSyntaxIdLSL::isSupportedVersion(const LLSD& content)
}
//-----------------------------------------------------------------------------
-// loadDefaultKeywordsIntoLLSD()
-//-----------------------------------------------------------------------------
-void LLSyntaxIdLSL::loadDefaultKeywordsIntoLLSD()
-{
- mSyntaxId.setNull();
- buildFullFileSpec();
- loadKeywordsIntoLLSD();
-}
-
-//-----------------------------------------------------------------------------
-// loadKeywordsFileIntoLLSD
+// loadKeywordsIntoLLSD
//-----------------------------------------------------------------------------
/**
* @brief Load xml serialized LLSD
- * @desc Opens the specified filespec and attempts to deserializes the
- * contained data to the specified LLSD object. indicate success/failure with
- * sLoaded/sLoadFailed members.
+ * @desc Open the internal lsl keywords files and deserialize them into the correct
+ * members.
*/
-void LLSyntaxIdLSL::loadKeywordsIntoLLSD()
+void LLSyntaxDefCache::loadKeywordsIntoLLSD()
{
- LLSD content;
- llifstream file;
- file.open(mFullFileSpec.c_str());
- if (file.is_open())
+ for (auto& filename : MEMCACHED_LLSD)
{
- if (LLSDSerialize::fromXML(content, file) != LLSDParser::PARSE_FAILURE)
+ // Note, in the case of the legacy language cap (it only delivers the LSL keywords file)
+ // The mFileCachePaths will have been initialized in such a way that the Lua keywords
+ // point to the default file.
+ std::string full_path = mFileCachePaths.getPath(filename);
+ if (!full_path.empty())
{
- if (isSupportedVersion(content))
+ LLSD content = loadDeserializedCacheFile(full_path);
+ if (!content.isUndefined() && isSupportedVersion(content))
{
- LL_DEBUGS("SyntaxLSL") << "Deserialized: " << mFullFileSpec << LL_ENDL;
+ LL_DEBUGS("SyntaxLSL") << "Deserialized cached file: " << full_path << LL_ENDL;
+ if (filename == FILENAME_INTERNAL_LSL)
+ {
+ mLSLKeywords = content;
+ }
+ else if (filename == FILENAME_INTERNAL_LUA)
+ {
+ mLuaKeywords = content;
+ }
}
else
{
- LL_WARNS("SyntaxLSL") << "Unknown or unsupported version of syntax file." << LL_ENDL;
+ LL_WARNS("SyntaxLSL") << "Unknown or unsupported version of syntax file " << full_path << "." << LL_ENDL;
}
}
}
- else
- {
- LL_WARNS("SyntaxLSL") << "Failed to open: " << mFullFileSpec << LL_ENDL;
- }
- mKeywordsXml = content;
- mSyntaxIDChangedSignal();
-}
-bool LLSyntaxIdLSL::keywordFetchInProgress()
-{
- return !mInflightFetches.empty();
+ mSyntaxIDChangedSignal();
}
-void LLSyntaxIdLSL::handleRegionChanged()
+std::vector<std::string> LLSyntaxDefCache::getCacheFileNames() const
{
- if (syntaxIdChanged())
+ std::vector<std::string> names;
+ for (const auto& [name, path] : mFileCachePaths)
{
- buildFullFileSpec();
- fetchKeywordsFile(mFullFileSpec);
- mInitialized = false;
+ names.push_back(name);
}
+ return names;
}
-void LLSyntaxIdLSL::handleCapsReceived(const LLUUID& region_uuid)
+LLSD LLSyntaxDefCache::loadDeserializedCacheFile(const std::string& file_path)
{
- LLViewerRegion* current_region = gAgent.getRegion();
-
- if (region_uuid.notNull()
- && current_region->getRegionID() == region_uuid)
+ std::ifstream file(file_path.c_str());
+ if (file.good())
{
- syntaxIdChanged();
+ LLSD content;
+ if (LLSDSerialize::deserialize(content, file, -1))
+ {
+ return content;
+ }
}
+ else
+ {
+ LL_WARNS("SyntaxLSL") << "Failed to open cached file: " << file_path << LL_ENDL;
+ }
+ return LLSD();
}
-boost::signals2::connection LLSyntaxIdLSL::addSyntaxIDCallback(const syntax_id_changed_signal_t::slot_type& cb)
-{
- return mSyntaxIDChangedSignal.connect(cb);
-}
-
-
-
-//-----------------------------------------------------------------------------
-// LLSyntaxLua
-//-----------------------------------------------------------------------------
-LLSyntaxLua::LLSyntaxLua()
- : mKeywordsXml(LLSD())
- , mInitialized(false)
-{
-}
-
-void LLSyntaxLua::initialize()
-{
- if (mInitialized) return;
-
- loadDefaultKeywordsIntoLLSD();
- loadLuaTypesIntoLLSD();
- mInitialized = true;
-}
-
-void LLSyntaxLua::loadDefaultKeywordsIntoLLSD()
+std::string LLSyntaxDefCache::loadCacheFile(const std::string& name) const
{
- std::string fullFileSpec = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, FILENAME_DEFAULT_LUA);
- llifstream file(fullFileSpec.c_str());
-
- if (file.good())
+ std::string full_path = mFileCachePaths.getPath(name);
+ if (!full_path.empty())
{
- LLSD content;
- if (LLSDSerialize::fromXML(content, file) != LLSDParser::PARSE_FAILURE)
+ std::ifstream file(full_path.c_str());
+ if (file.good())
+ {
+ std::ostringstream ss;
+ ss << file.rdbuf();
+ return (file.good()) ? ss.str() : std::string();
+ }
+ else
{
- mKeywordsXml = content;
+ LL_WARNS("SyntaxLSL") << "Failed to open cached file: " << full_path << LL_ENDL;
}
}
+ return std::string();
}
-void LLSyntaxLua::loadLuaTypesIntoLLSD()
+LLSD LLSyntaxDefCache::loadCacheFileAsLLSD(const std::string& name) const
{
- std::string fullFileSpec = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "types_lua_default.xml");
- llifstream file(fullFileSpec.c_str());
-
- if (file.good())
+ std::string full_path = mFileCachePaths.getPath(name);
+ if (!full_path.empty())
{
- LLSD content;
- if (LLSDSerialize::fromXML(content, file) != LLSDParser::PARSE_FAILURE)
- {
- mTypesXml = content;
- }
+ return loadDeserializedCacheFile(full_path);
}
+ return LLSD();
}
diff --git a/indra/newview/llsyntaxid.h b/indra/newview/llsyntaxid.h
index 51103e3396..acf8020d58 100644
--- a/indra/newview/llsyntaxid.h
+++ b/indra/newview/llsyntaxid.h
@@ -25,8 +25,7 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-#ifndef LL_SYNTAXID_H
-#define LL_SYNTAXID_H
+#pragma once
#include "llviewerprecompiledheaders.h"
@@ -34,66 +33,117 @@
#include "lleventcoro.h"
#include "llcoros.h"
-class fetchKeywordsFileResponder;
-
-class LLSyntaxIdLSL : public LLSingleton<LLSyntaxIdLSL>
+class LLSyntaxDefCache : public LLSingleton<LLSyntaxDefCache>
{
- LLSINGLETON(LLSyntaxIdLSL);
- friend class fetchKeywordsFileResponder;
+ LLSINGLETON(LLSyntaxDefCache) = default;
public:
using syntax_id_changed_signal_t = boost::signals2::signal<void()>;
using syntax_id_changed_h = boost::signals2::connection;
+ class cache_names_t
+ {
+ public:
+ using name_path_map_t = std::unordered_map<std::string, std::string>;
+ using iterator = name_path_map_t::iterator;
+ using const_iterator = name_path_map_t::const_iterator;
+
+ cache_names_t() = default;
+ ~cache_names_t() = default;
+
+ std::string getPath(const std::string &name) const
+ {
+ auto it = mNamePathMap.find(name);
+ if (it != mNamePathMap.end())
+ {
+ return it->second;
+ }
+ return std::string();
+ }
+
+ bool hasName(const std::string &name) const
+ {
+ return mNamePathMap.find(name) != mNamePathMap.end();
+ }
+
+ void addNamePath(const std::string &name, const std::string &path)
+ {
+ mNamePathMap[name] = path;
+ }
+
+ iterator begin() { return mNamePathMap.begin(); }
+ const_iterator begin() const { return mNamePathMap.begin(); }
+ iterator end() { return mNamePathMap.end(); }
+ const_iterator end() const { return mNamePathMap.end(); }
- void initialize();
- bool keywordFetchInProgress();
- LLSD getKeywordsXML() const { return mKeywordsXml; };
+ size_t size() const { return mNamePathMap.size(); }
+ void clear() { mNamePathMap.clear(); }
+ bool empty() const { return mNamePathMap.empty(); }
+
+ iterator find(const std::string &name) { return mNamePathMap.find(name); }
+ const_iterator find(const std::string &name) const { return mNamePathMap.find(name); }
+
+ private:
+ name_path_map_t mNamePathMap;
+ };
+
+ bool keywordFetchInProgress() const { return !mInflightFetches.empty(); }
+ LLSD getLSLKeywords() const { return mLSLKeywords; };
+ LLSD getLuaKeywords() const { return mLuaKeywords; };
LLUUID getSyntaxID() const { return mSyntaxId; }
syntax_id_changed_h addSyntaxIDCallback(const syntax_id_changed_signal_t::slot_type& cb);
-private:
- std::set<std::string> mInflightFetches;
- syntax_id_changed_signal_t mSyntaxIDChangedSignal;
- syntax_id_changed_h mRegionChangedCallback;
+ bool checkCacheAndLoad(const LLUUID& syntax_id);
- bool syntaxIdChanged();
- bool isSupportedVersion(const LLSD& content);
- void handleRegionChanged();
- void handleCapsReceived(const LLUUID& region_uuid);
- void setKeywordsXml(const LLSD& content) { mKeywordsXml = content; };
- void buildFullFileSpec();
- void fetchKeywordsFile(const std::string& filespec);
- void loadDefaultKeywordsIntoLLSD();
- void loadKeywordsIntoLLSD();
+ static std::string buildCacheDirectoryName(const LLUUID& syntax_id);
- void fetchKeywordsFileCoro(std::string url, std::string fileSpec);
- void cacheFile(const std::string &fileSpec, const LLSD& content_ref);
+ using const_iterator = cache_names_t::const_iterator;
- std::string mCapabilityURL;
- std::string mFullFileSpec;
- ELLPath mFilePath;
- LLUUID mSyntaxId;
- LLSD mKeywordsXml;
- bool mInitialized;
+ const_iterator begin() const { return mFileCachePaths.begin(); }
+ const_iterator end() const { return mFileCachePaths.end(); }
-};
+ size_t size() const { return mFileCachePaths.size(); }
+ bool empty() const { return mFileCachePaths.empty(); }
+ const_iterator find(const std::string& name) const { return mFileCachePaths.find(name); }
-class LLSyntaxLua : public LLSingleton<LLSyntaxLua>
-{
- LLSINGLETON(LLSyntaxLua);
+ std::vector<std::string> getCacheFileNames() const;
+ bool hasCacheFile(const std::string& name) const { return mFileCachePaths.hasName(name); }
+ std::string loadCacheFile(const std::string& name) const;
+ LLSD loadCacheFileAsLLSD(const std::string& name) const;
-public:
- void initialize();
- LLSD getKeywordsXML() const { return mKeywordsXml; }
- LLSD getTypesXML() const { return mTypesXml; }
+protected:
+ void initSingleton() override;
+ void cleanupSingleton() override;
private:
- void loadDefaultKeywordsIntoLLSD();
- void loadLuaTypesIntoLLSD();
- LLSD mKeywordsXml;
- LLSD mTypesXml;
- bool mInitialized;
-};
-#endif // LLSYNTAXID_H
+ bool updateSyntaxId();
+ static bool isSupportedVersion(const LLSD& content);
+ void handleRegionChanged();
+ void handleCapsReceived(const LLUUID& region_uuid);
+ void setKeywords(const LLSD& lsl, const LLSD& lua) { mLSLKeywords = lsl; mLuaKeywords = lua; };
+
+ void loadKeywordsIntoLLSD();
+
+ void fetchKeywords();
+ void fetchKeywordsFileCoro(std::string url, LLUUID syntax_id);
+ void fetchKeywordsDefsCoro(std::string url, LLUUID syntax_id);
+
+ bool checkLocalCache(const LLUUID& syntax_id) const;
+ void buildDefaultCache() { buildCachePaths(LLUUID::null); }
+ void buildCachePaths(const LLUUID &syntax_id);
+ bool writeCacheFile(const std::string &fileSpec, const LLSD& content_ref);
+
+ static LLSD loadDeserializedCacheFile(const std::string& file_path);
+
+ std::set<LLUUID> mInflightFetches;
+ syntax_id_changed_signal_t mSyntaxIDChangedSignal;
+ syntax_id_changed_h mRegionChangedCallback;
+
+ std::string mCapabilityURL;
+ cache_names_t mFileCachePaths;
+ LLUUID mSyntaxId;
+ LLSD mLSLKeywords;
+ LLSD mLuaKeywords;
+ bool mUseDefsCap{ false };
+};
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 42a587f376..eed118e7d0 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -3291,6 +3291,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("RequestTextureDownload");
capabilityNames.append("ResourceCostSelected");
capabilityNames.append("RetrieveNavMeshSrc");
+ capabilityNames.append("ScriptDefinitions");
capabilityNames.append("SearchStatRequest");
capabilityNames.append("SearchStatTracking");
capabilityNames.append("SendPostcard");
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 21e50f4dcb..524077f1b2 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -64,6 +64,16 @@ class ViewerManifest(LLManifest):
super(ViewerManifest, self).construct()
self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg")
+ # ... and the lsl/lua script definition files (needed at build time and packaging)
+ pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
+ with self.prefix(src=os.path.join(pkgdir, 'lsl_definitions'), dst="app_settings/syntax_default"):
+ self.path("*.txt")
+ self.path("*.yaml")
+ self.path("*.xml")
+ self.path("*.json")
+ self.path("*.luau")
+ self.path("*.yml")
+
if self.is_packaging_viewer():
with self.prefix(src_dst="app_settings"):
self.exclude("logcontrol.xml")
@@ -92,7 +102,7 @@ class ViewerManifest(LLManifest):
with self.prefix(src=pkgdir):
self.path("dictionaries")
- # include the extracted packages information (see BuildPackagesInfo.cmake)
+ # include the extracted packages information
self.path(src=os.path.join(self.args['build'],"packages-info.txt"), dst="packages-info.txt")
# CHOP-955: If we have "sourceid" or "viewer_channel" in the
# build process environment, generate it into